Reputation: 2335
I've got a query regarding a query I am writing in LINQ which I hope someone can help with. Basically I have the following (example data)
ProductCode LanguageID LegislationId Version
1234 English UK 1
1234 English UK 2
5678 English UK 1
9999 English UK 1
9999 English UK 2
9999 Spanish Spain 1
So, what I need to do is return records based on criteria provided by the user, including the LanguageID and Description. The tricky part here is that where there are multiple versions of the same product code, language and legislation then I only want to return the latest version.
So...my code as it stands is as follows (pLegislations contains a comman separated list of legislations):
List<string> legList = pLegislations.Split(',').ToList();
IEnumerable<MyClass> results = null;
results = (from a in context.ALLProducts
let prodCode = a.ProductCode
let prodDesc = a.ProductDescription
where legList.Contains(a.LegislationID) &&
(a.LanguageID == pLanguage || pLanguage == null) &&
a.BrandName == pMarket &&
(prodCode.Contains(pSearch) || prodDesc.Contains(pSearch) ||
pSearch == string.Empty) &&
prodCode[0] != 'x' &&
((pMarket == "testMarket") ? prodCode.StartsWith("0") : true)
select new MyClass
{
BrandName = a.BrandName,
BulkCode = prodCode,
BulkDescription = prodDesc,
Language = a.LanguageName,
LanguageCode = a.LanguageID
}).ToList();
Now this all works fine where there are not multiple versions, so my question is - how can I filter it so only the latest version is returned when there is a match on ProductCode, Language and Legislation, i.e. if I was to pass Language = 'English' and Legislation = 'UK' then I'd expect the following results:
ProductCode LanguageID LegislationId Version
1234 English UK 2
5678 English UK 1
9999 English UK 2
9999 Spanish Spain 1
Thanks in advance
Andrew
Upvotes: 1
Views: 1480
Reputation: 236188
Group results by ProductCode
(1) and select from each group item with max Version
value (2):
results = (from a in context.ALLProducts
let prodCode = a.ProductCode
let prodDesc = a.ProductDescription
where legList.Contains(a.LegislationID) &&
(a.LanguageID == pLanguage || pLanguage == null) &&
a.BrandName == pMarket &&
(prodCode.Contains(pSearch) ||
prodDesc.Contains(pSearch) ||
pSearch == string.Empty) &&
prodCode[0] != 'x' &&
((pMarket == "testMarket") ? prodCode.StartsWith("0") : true)
group a by a.ProductCode into g // 1
let lastProduct = g.OrderByDescending(x => x.Version).First() // 2
select new MyClass
{
BrandName = lastProduct.BrandName,
BulkCode = prodCode,
BulkDescription = prodDesc,
Language = lastProduct.LanguageName,
LanguageCode = lastProduct.LanguageID
}).ToList();
Upvotes: 1