How can i select take 1 each data in column in linq that only return 1 row. Because when i put .Take(1) only 1 row result will appear but i want to have 2 row result with different entry
to make it clear here's what i mean
in c# here's my query
using (PharmacyDBEntities entities = new PharmacyDBEntities())
{
var positem = (from a in entities.POSEntries.Take(1)
where a.Invoice.AccountID == authLogin.userid && a.Invoice.InvoiceStatusID == 1
select new
{
a.Item.ItemCode,
a.Item.Name,
Quantity = (from b in entities.POSEntries where b.Invoice.AccountID == authLogin.userid && b.Invoice.InvoiceStatusID == 1 select b).Count(),
a.Item.SellingPrice
}).ToList();
gcItemList.DataSource = positem;
}
And the result
Is there any suggestion guys? will make big help to me. thanks
You can use Linq GroupBy
var positem = entities.POSEntries.Where( a=> a.Invoice.AccountID == authLogin.userid && a.Invoice.InvoiceStatusID == 1)
.GroupBy(x=>x.Item.ItemCode).Select(g=> new {
g.Key,
g.First().Item.Name,
Quantity = g.Count(),
g.First().Item.SellingPrice
}).ToList();
So, you want Distinct() instead of Take(1)? Something along these lines:
var positem = (from a in entities.POSEntries
where a.Invoice.AccountID == authLogin.userid && a.Invoice.InvoiceStatusID == 1
select new
{
a.Item.ItemCode,
a.Item.Name,
Quantity = (from b in entities.POSEntries where b.Invoice.AccountID == authLogin.userid && b.Invoice.InvoiceStatusID == 1 select b).Count(),
a.Item.SellingPrice
}).Distinct().ToList();
Take only returns first n elements. I think you need to try using the Distinct method.
Related
In my query I am getting records based on RoleId and LocationId, some times the user may not pass location in that case I want to remove that filter and get information from all locations.
Currently I am doing this way
if(loc > 0)
{
var myResult = (from x in CSDB.Allocations
join s in CSDB.Managers
on x.ManagerId equals s.Id
Where x.RoleId == 2 && s.LocationId == loc
select new
{
x.name,
x.Date
}).ToList();
}
else
{
var myResult = (from x in CSDB.Allocations
join s in CSDB.Managers
on x.ManagerId equals s.Id
Where x.RoleId == 2
select new
{
x.name,
x.Date
}).ToList();
}
I am seeing if I can check if loc is null or not inside the query instead of using if else.
You can do something like this:
Where x.RoleId == 2 && (loc == null || s.LocationId == loc)
Also, you can do smth like this.
Where x.RoleId == 2 && (loc?.Equals(s.LocationId) ?? true)
If loc just int I would prefer to use a little bit changed #Salah Akbari answer:
Where x.RoleId == 2 && (loc == 0 || s.LocationId == loc)
Simply extract your managers and filter them if needed. That way you can as well easily apply more filters and code readability isn't hurt.
var managers = CSDB.Managers.AsQueryable();
if(loc > 0)
managers = managers.Where(man => man.LocationId == loc);
var myResult = from allocation in CSDB.Allocations
join manager in managers on allocation.ManagerId equals manager.Id
where allocation.RoleId == 2
select new
{
allocation.name,
allocation.Date
};
I have a DataTable and a SQLTable . I want to write a linq Qurty to create a result that has Information from both tables. I wrote this code. but it runs very slowly. How can I optimize it?
var Result = (from DataRow row in dTable.Rows
from obj in db.SQLTable
where (
obj.Status != "Suspend" &&
(
(obj.Type.ToLower() == "a" && obj.Code ==
row[2].ToString()) ||
(obj.Type.ToLower() == "b" &&
obj.Code.Substring(6) == row[2].ToString())
)
select new
{
ID = obj.ID,
RowNum = row[0],
}).ToList();
I'm not sure if this is 100% the correct syntax.
The idea here is that we select calculated columns to join against. That way we're calculating the obj.Type.ToLower() and obj.Code.Substring(6) once per row (n times), rather than once per join instance (n*m times).
var Result = (from DataRow row in dTable.Rows
from obj in (db.SQLTable).Select(x => new {x.Status, ObjTypeLower = x.Type.ToLower(), x.Code, ObjCodeSub = x.Code.Substring(6)})
where (
obj.Status != "Suspend" &&
(
(obj.ObjTypeLower == "a" && obj.Code ==
row[2].ToString()) ||
(obj.ObjTypeLower == "b" &&
obj.ObjCodeSub == row[2].ToString())
)
select new
{
ID = obj.ID,
RowNum = row[0],
}).ToList();
try something like this
var result=(from e in db.Users
select e.UserID).Except(from m in db.Fi
select m.UserID).ToList();
I am trying to write a LINQ query that will get me some distinct values from two SQL Server data tables.
I have two tables named, Facility_Cost_TBL and Tenant_Bills_TBL.
I then have a column that is named Nursing_Home_Name which I am trying to get the distinct data from.
This is my effort in LINQ , however it does not work,
var name = (from f in dataContext.Facility_Cost_TBLs
join t in dataContext.Tenant_Bills_TBLs on f.Tenant_Code equals t.Tenant_Code
where f.Tenant_Code == code && f.Date_Month == date.Month && f.Date_Year == date.Year
select new {Facility_Cost_TBL = f, Tenant_Bills_TBL = t}).Distinct();
And this is a working SQL statement I made that does what I want via T-SQL.
SELECT DISTINCT Nursing_Home_Name
FROM (SELECT Nursing_Home_Name
FROM Facility_Cost_TBL
WHERE Date_Year = 2016 AND Date_Month = 10 AND Tenant_Code = 664250
UNION SELECT Nursing_Home_Name
FROM Tenant_Bills_TBL
WHERE Year_Data = 2016 AND Month_Data = 10 AND Tenant_Code = 664250)
a
Could someone show me what LINQ sytax AND what LINQ extension method query would look like?
Please try following
var names = ((from f in dataContext.Facility_Cost_TBLs
where f.Tenant_Code == "664250" && f.Date_Month == "10" && f.Date_Year == "2016"
select new { Nursing_Home_Name = f.Nursing_Home_Name }).
Union(
from t in dataContext.Tenant_Bills_TBLs
where t.Tenant_Code == "664250" && t.Date_Month == "10" && t.Date_Year == "2016"
select new { Nursing_Home_Name = t.Nursing_Home_Name })).ToList();
Hope this will help you
Try this to see if this works. LINQ to SQL: Multiple joins ON multiple Columns. Is this possible?
var name = (from f in dataContext.Facility_Cost_TBLs
join t in dataContext.Tenant_Bills_TBLs equals on new { f.Tenant_Code, f.Date_Month, f.Date_Year } equals new { t.Tenant_Code, t.Date_Month, t.Date_Year }
where f.Tenant_Code == code && f.Date_Month == date.Month && f.Date_Year == date.Year
select new {Facility_Cost_TBL = f, Tenant_Bills_TBL = t}).Distinct();
I am getting the following results for
string[] proj = Pid.Split(',');
"1032,1222" --> [0]=1032,[1]=1222
but I want to use in LINQ query. This is my LINQ query. Where to use it and how to use it?
string[] proj = Pid.Split(',');
var data2 = (from p in Db.emp.AsEnumerable()
join r in Db.use on p.EmployeeId equals r.EmployeeId
join q in Db.proo on p.EmployeeId equals q.EmpId
where (q.IsDelete == false && p.IsDelete == false && p.RoleID != 1 && p.RoleID != 2 && q.ProId == Convert.ToInt32(Pid))
select new GroupSelectedModel {
Text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(p.FirstName + " " + p.LastName),
Value = r.UserId.ToString(),
StatusId = Convert.ToInt32(p.Status)
})
.Distinct().ToList().OrderBy(r => r.Text);
return data2.OrderBy(p => p.StatusId).ToList();
Please check above mentioned code.
When you need IN, you have to invert it, and use Contains(). Your post is not very clear, but I think you're asking for something like this (note you need to use a List instead of an array):
List<string> proj = new List<string>(Pid.Split(','));
where (q.IsDelete == false && p.IsDelete == false && p.RoleID != 1 && p.RoleID != 2 && proj.Contains(q.ProId))
I'm populating a FormView by setting the datasource to an IQueryable object that I get by doing a LINQ query. Basically it returns the number of employees that hold a certain "Position" within a certain "Shift".
int shiftID = 1;
var shiftCount = from x in context.Employees.Take(1)
select new
{
ManagerCount = ((from p in context.Persons
where p.PositionID == 1 && p.ShiftID == shiftID && p.IsEmployee == true
select p.PersonId).Count(),
PartTimeCount = ((from p in context.Persons
where (p.PositionID == 2 || p.PositionID == 3) && p.ShiftID == shiftID && p.IsEmployee == true
select p.PersonId).Count(),
etc, etc...
};
That part works fine. However, when I want to get the number of employees for all shifts, I can't quite figure out how to do it:
//Get all shifts 1, 2, and 3
var shiftCount = from x in context.Employees.Take(1)
select new
{
ManagerCount = ((from p in context.Persons
where p.PositionID == 1 && (p.ShiftID == 1 || p.ShiftID == 2 || p.ShiftID == 3) && p.IsEmployee == true
select p.PersonId).Count()
};
That doesn't work though because it of course returns 3 values and gives the Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. error.
So I need to get the sum of the three values returned (it's not always three though, it depends on the position).
I've looked at various ways using Sum and LINQ grouping, but can't quite seem to work it out. Can anybody point me in the right direction?
I've got a few answers for you, but first it seems like you have something wrong with your first part of your query. You're doing .Take(1) on Employees which will give you only one x value. Since you don't use x in the remainder of your query then using Employees is redundant.
Now, since all of your queries are quite similar I've tried to remove repetition. The first thing to do is to get a common filter for the shifts you are filtering on.
If you have a single shift, use this:
int shiftID = 1;
var shifts = new [] { shiftID, };
If you have multiple shifts, use this:
var shifts = new [] { 1, 2, 3, };
Either way you end up with an array of integers representing the shifts you want to filter against. All of the below answers require this shifts array.
Then define a query for the employees in those shift, regardless of position for now.
var employeesInShifts =
from p in context.Persons
where p.IsEmployee
where shifts.Contains(p.ShiftID)
select p;
So you can then get the shift counts like so:
var shiftCount =
new
{
ManagerCount = employeesInShifts
.Where(p => p.PositionID == 1)
.Count(),
PartTimeCount = employeesInShifts
.Where(p => p.PositionID == 2 || p.PositionID == 3)
.Count(),
// etc
};
Perhaps a better alternative for you though, would be to turn the employeesInShifts query into a dictionary and then just pluck the values from the dictionary.
var employeesInShifts =
(from p in context.Persons
where p.IsEmployee
where shifts.Contains(p.ShiftID)
group p by p.PositionID into gps
select new
{
PositionID = gps.Key,
Count = gps.Count(),
})
.ToDictionary(pc => pc.PositionID, pc.Count);
var shiftCount =
new
{
ManagerCount = employeesInShifts[1],
PartTimeCount = employeesInShifts[2] + employeesInShifts[3],
// etc
};
The downside to this approach is that you really should check that the dictionary has values for each PositionID before getting the values.
That can be fixed by introducing an array of position ids that you want the dictionary to have and joining your results on that.
var positionIDs = new [] { 1, 2, 3, };
var employeesInShifts =
(from p in context.Persons
where p.IsEmployee
where shifts.Contains(p.ShiftID)
where positionIDs.Contains(p.PositionID)
select p).ToArray();
var allPositionEmployeesInShifts =
from pid in positionIDs
join p in employeesInShifts on pid equals p.PersonId into gps
select new
{
PositionID = pid,
Count = gps.Count(),
};
var countOfPositionID =
allPositionEmployeesInShifts
.ToDictionary(x => x.PositionID, x => x.Count);
var shiftCount =
new
{
ManagerCount = countOfPositionID[1],
PartTimeCount = countOfPositionID[2] + countOfPositionID[3],
// etc
};
Now that guarantees that your final dictionary will contain the counts of all of the position ids that you are wanting to query.
Let me know if this works or if you really needed to join on the Employees table, etc.
I would recommend looking at the Group By examples here: