Need to group LINQ to Entities Results - c#

Here is my code:
var context = new InventoryContext();
var res = from i in context.Inventories
select new FullInventory
{
InventoryID = i.InventoryID,
ItemModelID = i.ItemModelID,
ModelName = i.ItemModel.ModelName,
...
Quantity = context.Inventories.Select(x => x.ItemModelID).Count()
};
return res.ToList();
The code I have works great, however the results look like this:
CATEGORY | MANUFACTURER | MODEL | QUANTITY
1. Hard drive | Dell | 250GB | 2
2. Hard drive | Dell | 250GB | 2
As you can see, I have 2 entries in the table and since those entries are exactly the same, I would like them to be grouped together. To group them together I need to group by ItemModelID, however I still need to put all of the data into a list of FullInventory classes.
How can I group my data together while still "selecting" the data into a list of FullInventory classes?

Group by that value and then just select out the first item from each group using let.
var res = from inventory in context.Inventories
group inventory by inventory.ItemModelID into model
let i = model.FirstOrDefault()
select [...]

I would attempt the Group By after retrieving the full list with a Lambda expression:
var context = new InventoryContext();
return (from i in context.Inventories
select new FullInventory
{
InventoryID = i.InventoryID,
ItemModelID = i.ItemModelID,
ModelName = i.ItemModel.ModelName,
...
Quantity = context.Inventories.Select(x => x.ItemModelID).Count()
}).GroupBy(g => g.ItemModelID).ToList();

You may use Distinct()
return res.Distinct().ToList()

Related

Get Data From two Lists conditionally using LINQ Entity Framework

I have two Lists:
using (DBEntities context = new DBEntities()) {
var userInfoList = context.UsersInfoes.ToList();
var membersList = context.Members.ToList();
}
These two list are represented on tables as below;
I want to be able to iterate through both lists WHERE THE TEAMID is equal to '10' and add FKUserID and Name to a third list where FKUserID is matching in both tables.
Is there anyway I can do this as efficiently as possible and produce these results in the third list?
You could use a linq join clause as follows:
var ThirdList =
from member in MembersList
join userInfo in UserInfoList on member.FKUserID equals userInfo.FKUserID
where member.TeamID == 12 // change 12 to the TeamID needed
select new { TeamID = member.TeamID, FKUserID = member.FKUserID, Name = userInfo.Name};
foreach(var tlist in ThirdList)
{
Console.WriteLine("{0} | {1} | {2}", tlist.TeamID, tlist.FKUserID, tlist.Name);
}
Output:
12 | 6 | kjh
12 | 7 | ghg
12 | 8 | dfi
I haven't tested this LINQ but it should work. You said you wanted TeamID = 10, but used 12 in your tables. Obviously, just change the 12 to whatever you want the TeamID to be.
var ThirdList = (from y in userInfoList join z in membersList on y.FKUserID equals z.FKUserID
where z.TeamID == 12
select new {
TeamID = z.TeamID,
FKUserID = z.FKUserID,
Name = y.Name
} ).ToList();

Linq Grouping items by property

I'm trying to group an object by one property (State). The end goal is to have a list. And within each list is an object consisting of two properties. I have data that looks like the following...
State Name ID
CA John 12
CA Kevin 13
CA Joe 14
AZ Sally 15754
AZ Stuart 1263
TN Sam 1211
How would one go about using linq to make this a list of object 'People' consisting of a person's name and ID grouped by state? This is what I've tried...but it's not working
var result = from groupOne in dataset
group groupOne by OneGroup.State into g
select new People() { People = g.ToList() }.ToList();
Why are you grouping by OneGroup.State, when OneGroup is not a part of the query?
That one should do the trick:
var result = from groupOne in dataset
group groupOne by groupOne.State into g
select new {
State = g.Key,
People = g.Select(x => new { x.Name, x.ID })
};
It returns anonymous types, but you can easily change it to return your class objects if you need.

How to do Many To Many LINQ entity grouping queries?

I can see many examples on this site of the sort of queries I'm after, but I can't relate to them and how they work. I was wondering if you could help me.
I have set up my many-to-many tables and relationships with entity designer in Visual Studio.
tblQuotes
ID | QuoteNo | Date
tblItems
ID | PartNo | Desc
tblSuppliers
ID | Supplier | email
tblQIS (quotes items suppliers)
ID | SupplierID | QuoteID | ItemID
I've put some test data in and have begun to try to type this, but I think I first need to group by quoteNo then group by supplier, to get the details in the correct view.
var tblQuotes = from d in db.tblQuotes_Items_Suppliers
.Include(t => t.tblItems)
.Include(t => t.tblQuotes)
.Include(t => t.tblSuppliers)
group by (d.QuoteID,d.SupplierID)
select d;
Can anyone help me out?
you could try this:
var tblQuotes =
from d in db.tblQuotes_Items_Suppliers // or tblQIS whatever the name
group d by new
{
d.QuoteID,
d.SupplierID
} into g
select g;
that would give you Quotes grouped by both QuoteID and SupplierID
Update
the tblQuotes is a list (IQueryable) of grouped quotes, so you can access other entities as follow:
var firstGroupOfQuotes = tblQuotes.First(); // will give you the first group of quotes
var firstQuote = firstGroupOfQuotes.First(); // will give you the first quote in the first group
var item = firstQuote.tblItems; // will give you the item of this quote
var partNo = item.PartNo; // will give you the PartNo of this item

LINQ GroupBy, whilst keeping all object fields

I've currently got this sample table of data:
ID | Policy ID | History ID | Policy name
1 | 1 | 0 | Test
2 | 1 | 1 | Test
3 | 2 | 0 | Test1
4 | 2 | 1 | Test1
Out of this, I want to group by the Policy ID and History ID (MAX), so the records I want to be kept are ID's 2 and 4:
ID | Policy ID | History ID | Policy name
2 | 1 | 1 | Test
4 | 2 | 1 | Test1
I've tried to do this in LINQ and stumbling on the same issue every time. I can group my entities, but always into a group where I have to re-define the properties, rather than have them kept from my Policy objects. Such as:
var policies = _context.Policies.GroupBy(a => a.intPolicyId)
.Select(group => new {
PolicyID = group.Key,
HistoryID = group.Max(a => a.intHistoryID)
});
This simply just brings out a list of objects which have "Policy ID" and "History ID" within them. I want all the properties returned from the Policies object, without having to redefine them all, as there are around 50+ properties in this object.
I tried:
var policies = _context.Policies.GroupBy(a => a.intPolicyId)
.Select(group => new {
PolicyID = group.Key,
HistoryID = group.Max(a => a.intHistoryID)
PolicyObject = group;
});
But this errors out.
Any ideas?
Group by composite key
_context.Policies.GroupBy(a => new {a.intPolicyId, *other fields*}).Select(
group=> new {
PolicyId = group.Key.intPolicyId,
HistoryId = group.Max(intHistoryId),
*other fields*
}
);
Another way - grab histories, than join back with the rest of the data, something like this (won't work out of the box, will require some refining)
var historyIDs = _context.Policies.GroupBy(a=>a.intPolicyId).Select(group => new {
PolicyID = group.Key,
HistoryID = group.Max(a => a.intHistoryID)
});
var finalData = from h in historyIDs
join p in _context.Policies on h.intPolicyId equals p.intPolicyId
select new {h.HistoryId, *all other policy fields*}
And yet another way, even simpler and not require a lot of typing :):
var historyIDs = _context.Policies.GroupBy(a=>a.intPolicyId).Select(group => new {
PolicyID = group.Key,
HistoryID = group.Max(a => a.intHistoryID)
});
var finalData = from h in historyIDs
join p in _context.Policies on h.PolicyId equals p.intPolicyId && h.HistoryId equals p.HistoryId
select p
Basically it's somewhat equivalent to the following SQL query:
select p.*
from Policy p
inner join (
select pi.policyId, max(pi.historyId)
from Policy pi
group by pi.policyId
) pp on pp.policyId = p.policyId and pp.historyId = p.historyId
In LINQ to Objects, I'd do this as
var policies = _context.Policies
.GroupBy(a => a.intPolicyId)
.Select(g => g.OrderByDescending(p => p.intHistoryID).First());
but your _context impleis there might be a database involved and I'm not 100% sure this will translate.
Basically it groups by the policy ID as you'd expect, then within each group orders by history ID and from each group selects the row with the highest history ID. It returns exactly the same type as is found in Policies.

Nested Selects in LINQ

I have the following model:
Schools with Many Majors
Majors with Many Offered Degrees (or just Degrees for Short).
+------+--------+--------+
|School| Major | Degree |
+------+--------+--------+
| UCLA |CompSci | B |
| UCLA |CompSci | M |
| UCLA |CompSci | D |
| UCLA |Math | B |
+------+--------+--------+
I'd like to retrieve all the degrees offered by a school, grouped by Majors (so majors is not repeated for each degree returned). How might I do that? I have the following code so far, but now I'm stuck.
var query = from school in schools
where school.Id == Id
select new
{
name = s.Name
majors = (from major in school.Majors
select new
{
majorname = major.Name
}).Distinct()
};
I'm not quite sure I know how to return the degrees for each distinct major.
I was able to solve this by checking out similar situations on SO and by using the group/by/into keywords.
var query = from school in schools
where school.Id == id
select new
{
name = school.Name,
majors = ( from major in school.Majors
group major.Degree by major.Name into sub
select new
{
m = sub.Key,
d = (from degree in sub
select degree.Name)
} )
};
Thanks so much everyone.
What about the following?
var query = schools
.Where(school => school.Id == Id)
.Select(school => new
{
Name = school.Name,
Majors = school.Majors.Select(major => major.Name).Distinct()
})
.GroupBy(obj => obj.Majors);
The only change to your code, other than desugaring the query syntax, is to change the Majors field to an IEnumerable<string> and to add a GroupBy call.
Simply make a Group By
var groupedBy= list.Where(c=> c.Id==Id).GroupBy(c=> c.Major);
foreach(var item in groupedBy )
{
var v=item.Select(c=> new {Major=item.Key,Degree=c.Degree });
}

Categories

Resources