I have the following LINQ
Dim z = (From d In db.GPSdevice
Where d.CompanyId = currentuser.CompanyId And d.Type = "Truck" Or d.Type = "Trailer"
Order By d.ListOrder Descending
Group d By d.Driver Into g = Group
Select g.FirstOrDefault())
I try to convert it to c#
var z = db.GPSdevices
.Where(p => p.CompanyId == companyID && p.Type == "Truck" || p.Type == "Trailer")
.OrderByDescending(p => p.ListOrder)
.GroupBy(p => p.Driver)
.Select(g => new { Group = g });
but not sure, how to convert Select g.FirstOrDefault()...
You can use the query syntax in C# too, no need to rewrite using the extension methods directly:
var z = (from d In db.GPSdevice
where (d.CompanyId == currentuser.CompanyId) && (d.Type == "Truck") || (d.Type == "Trailer")
orderby d.ListOrder descending
group d by d.Driver into g = group
select g.FirstOrDefault())
Just call g.FirstOrDefault() in your Select
var z = db.GPSdevices
.Where(p => p.CompanyId == companyID && p.Type == "Truck" || p.Type == "Trailer")
.OrderByDescending(p => p.ListOrder)
.GroupBy(p => p.Driver)
.Select(g => g.FirstOrDefault());
Related
I've been puzzling over this problem all morning and can't figure out how to do it in C#.
My SQL query as follows:
select a.CourseID,
a.UserID
from audit a
inner join results r on a.UserID = r.UserID
inner join Course c on a.CourseID = c.CourseID
where c.CourseType = 9 and a.Guid = 'A123F123D123AS123123'
and a.Result = 'Passed' and r.Class = 'Maths'
group by a.CourseID, a.UserID
order by a.UserID
returns exactly what I want, but I can't seem to translate it into linq format. (the format being used here is what is required in my job at the moment so please advise on this format)
So far I have the following:
var audits = auditRepository.Get(a => a.Course.CourseType == 9 && a.GUID == this.Company.GUID && a.Result == "Passed", null, null,
a => a.Course, a => a.User)
.Join(resultsRepository.Get(r => r.GUID == this.Company.GUID && r.Class == class),
a => a.UserID,
r => r.UserID,
(a, r) => new Audit
{
User = a.User,
Course = a.Course,
Result = a.Result,
Timestamp = a.Timestamp,
AuditID = a.AuditID,
UserID = a.UserID
}
)
.OrderByDescending(o => o.Timestamp)
.GroupBy(u => new { u.User, u.Course })
.Select(grp => grp.ToList())
.ToList();
However this returns duplicates.
Any advice is appreciated, thanks
H
Instead of
.Select(grp => grp.ToList())
Select only the first element from each group to exclude duplicates:
.Select(grp => grp.First())
If you need a count also:
.Select(t => new{grp = t.First(),cnt = t.Count()} )
Fix:
.Select(t => new { grp = t.First(), cnt = t.Select(s => s.AuditID).Distinct().Count() })
I have a array called searchWords, that is a dynamic array that stores peoples search words. I need to add an option for AND search. So the search will only retrieve items if both variables in searchWords contains for resultList. Now it is searchWords.Any. Will searchWords.All make this works?
var resultList = from c in context.Category
join q in context.Question on c.CategoryId equals q.CategoryId
join qf in context.QuestionFilter on q.QuestionId equals qf.QuestionId
join a in context.Answer on q.QuestionId equals a.QuestionId into QuestAnsw
from a2 in QuestAnsw.DefaultIfEmpty()
orderby c.SortOrder
orderby q.SortOrder
where qf.FilterId == filterKeyAsInt
&& q.Published == true
&& c.Published == true
&& q.CustomerId == customerId
&& (searchWords.Any(w => a2.Text.Contains(w))
|| searchWords.Any(w => c.Text.Contains(w))
|| searchWords.Any(w => q.Text.Contains(w)))
select new { Category = c, Question = q };
You can put multiple clauses inside an All(), e.g.
&& (searchWords.All(w =>
a2.Text.Contains(w) &&
c.Text.Contains(w) &&
q.Text.Contains(w)))
...
You can do this if use searchWords.All, but i think searchWords.Any is more intuitive.
var resultList = from c in context.Category
join q in context.Question on c.CategoryId equals q.CategoryId
join qf in context.QuestionFilter on q.QuestionId equals qf.QuestionId
join a in context.Answer on q.QuestionId equals a.QuestionId into QuestAnsw
from a2 in QuestAnsw.DefaultIfEmpty()
orderby c.SortOrder
orderby q.SortOrder
where qf.FilterId == filterKeyAsInt
&& q.Published == true
&& c.Published == true
&& q.CustomerId == customerId
&& !
(
searchWords.All(w => !a2.Text.Contains(w))
&& searchWords.All(w => !c.Text.Contains(w))
&& searchWords.All(w => !q.Text.Contains(w))
)
select new { Category = c, Question = q };
I want select grouped rows to a new model list.this is my code:
List<Model_Bulk> q = (from a in db.Advertises
join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
where a.AdvertiseActive == true
&& a.AdvertiseExpireDate.HasValue
&& a.AdvertiseExpireDate.Value > DateTime.Now
&& (a.AdvertiseObjectType == 1
|| a.AdvertiseObjectType == 2)
select c)
.GroupBy(a => a.CompanyID).Select(a => new Model_Bulk
{
CompanyEmail = a.CompanyContactInfo.Email,
CompanyID = a.CompanyID,
CompanyName = a.CompanyName,
Mobile = a.CompanyContactInfo.Cell,
UserEmail = a.User1.Email,
categories = a.ComapnyCategories
}).ToList();
After group by, i can not use Select and naturally this syntax error raised:
System.Linq.IGrouping' does not contain a definition for 'CompanyContactInfo' and no extension method 'CompanyContactInfo' accepting a first argument of type
System.Linq.IGrouping' could be found (are you missing a using directive or an assembly reference?)
If i try with SelectMany() method.but the result will repeated and groupby method not work properly:
List<Model_Bulk> q = (from a in db.Advertises
join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
where a.AdvertiseActive == true
&& a.AdvertiseExpireDate.HasValue
&& a.AdvertiseExpireDate.Value > DateTime.Now
&& (a.AdvertiseObjectType == 1
|| a.AdvertiseObjectType == 2)
select c)
.GroupBy(a => a.CompanyID).SelectMany(a => a).Select(a => new Model_Bulk
{
CompanyEmail = a.CompanyContactInfo.Email,
CompanyID = a.CompanyID,
CompanyName = a.CompanyName,
Mobile = a.CompanyContactInfo.Cell,
UserEmail = a.User1.Email,
categories = a.ComapnyCategories
}).ToList();
Instead of .SelectMany(a => a) you can use .Select(g => g.First()).That will give you the first item of each group.
(from a in db.Advertises
join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
where a.AdvertiseActive == true && a.AdvertiseExpireDate.HasValue && a.AdvertiseExpireDate.Value > DateTime.Now && (a.AdvertiseObjectType == 1 || a.AdvertiseObjectType == 2)
select c)
.GroupBy(a => a.CompanyID)
.Select(g => g.First())
.Select(a => new Model_Bulk
{
CompanyEmail = a.CompanyContactInfo.Email,
CompanyID = a.CompanyID,
CompanyName = a.CompanyName,
Mobile = a.CompanyContactInfo.Cell,
UserEmail = a.User1.Email,
categories = a.ComapnyCategories
}).ToList();
Note that this might not be supported, if that is the case add an AsEnumerable call before .Select(g => g.First())
You should understand that after you do GroupBy() in your LinQ expresstion you work with a group so in your example it will be good to write like this:
List<Model_Bulk> q =
(from a in db.Advertises join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
where a.AdvertiseActive == true
&& a.AdvertiseExpireDate.HasValue
&& a.AdvertiseExpireDate.Value > DateTime.Now
&& (a.AdvertiseObjectType == 1 || a.AdvertiseObjectType == 2)
select c)
.GroupBy(a => a.CompanyID)
.Select(a => new Model_Bulk
{
CompanyEmail = a.First().CompanyContactInfo.Email,
CompanyID = a.Key, //Note this line, it's can be happened becouse of GroupBy()
CompanyName = a.First().CompanyName,
Mobile = a.First().CompanyContactInfo.Cell,
UserEmail = a.First().User1.Email,
categories = a.First().ComapnyCategories
}).ToList();
Instead you could try something like this, instead of mixing query expressions and methods... (using FirstOrDefault() in the where / select as necessary)
(from a in db.Advertises
join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
group a by new { a.CompanyId } into resultsSet
where resultsSet.AdvertiseActive == true && resultsSet.AdvertiseExpireDate.HasValue && resultsSet.AdvertiseExpireDate.Value > DateTime.Now && (resultsSet.AdvertiseObjectType == 1 || resultsSet.AdvertiseObjectType == 2)
select new Model_Bulk
{
CompanyEmail = resultsSet.CompanyContactInfo.Email,
CompanyID = resultsSet.CompanyID,
CompanyName = resultsSet.CompanyName,
Mobile = resultsSet.CompanyContactInfo.Cell,
UserEmail = resultsSet.User1.Email,
categories = resultsSet.ComapnyCategories
}).ToList();
Trying to convert the below SQL query to LINQ, but I'm stuck at grouping by ClientCompany.
SELECT TOP 300 ClientCompany,
CASE WHEN MIN(FeatureID) = 12 THEN 1 ELSE 0 END as Sort
FROM Ad
LEFT JOIN AdFeature
ON Ad.ID = AdFeature.AdID
WHERE (AdFeature.FeatureID = 13 OR AdFeature.FeatureID = 12)
AND SiteID = 2
GROUP BY ClientCompany
ORDER BY Sort DESC
My attempt to convert this to LINQ:
(from a in Ads
join af in AdFeatures
on new {
join1 = a.ID,
join3 = 2
} equals new {
join1 = af.AdID,
join3 = af.SiteID
}
let sort = (
af.FeatureID == 12 ? 1 : 0
)
orderby sort descending
where af.FeatureID == 13 || af.FeatureID == 12
select new { a.ClientCompany, sort } ).Take(300)
How would I use MIN(FeatureID) and GROUP BY ClientCompany in LINQ, so that I only get a single row per ClientCompany back?
EDIT
This worked! Based on Daniel Hilgarth's answer. Is there anything that can go horribly wrong with this solution?
Ads.Join(AdFeatures, x => x.ID, x => x.AdID,
(a, af) => new { Ad = a, AdFeature = af })
.Where(x => x.AdFeature.FeatureID == 12 || x.AdFeature.FeatureID == 13)
.Where(x => x.AdFeature.SiteID == 2)
.GroupBy(x => x.Ad.ClientCompany)
.Select(g => new { ClientCompany = g.Key, Sort = g.Min(x => x.AdFeature.FeatureID) == 12 ? 1 : 0 })
.OrderByDescending(x => x.Sort)
.Take(300)
Try this:
Ads.Join(AdFeatures, x => x.FeatureID, x => x.FeatureID,
(a, af) => new { Ad = a, AdFeature = af })
.Where(x => x.AdFeature.FeatureID == 12 || x.AdFeature.FeatureID == 13)
.Where(x => x.AdFeature.SiteID == 2)
.GroupBy(x => x.Ad.ClientCompany)
.Select(g => new { ClientCompany = g.Key,
Sort = g.Min(x => x.AdFeature.FeatureID) == 12 ? 1 : 0 });
Please note, I changed the left outer join into an inner join, because your original query accesses AdFeature unconditionally, making it effectively an inner join .
hi I would write it like that
context.Ads.Where(ad => ad.AdFeatures.Any(feature => (feature.FeatureID == 13 || feature.FeatureID == 12) && feature.SiteID == 2))
.GroupBy(ad => ad.ClientCompany)
.Select(ads => new
{
cc = ads.Key, sort = ads.SelectMany(ad => ad.AdFeatures)
.Select(feature => feature.FeatureID)
.Min() == 12
})
.OrderBy(arg => arg.sort).Take(300);
Try this:
(from a in ads
join af in AdFeatures on a.ID equals af.AdID into g
from x in g.DefaultIfEmpty()
where x.FeatureID == 13 || x.FeatureID == 12
where x.SiteID == 2
orderby a.Sort descending
group a by a.ClientCompany into g2
from x2 in g2
let sort = g2.Select(T => T.FeatureID).Min() == 12 ? 1 : 0
select new { a.ClientCompany, Sort = sort }).Take(300);
Why do you need grouping anyway?
How do I convert this statement into LINQ?
SELECT Sum(Balance) FROM account WHERE name='stocks' AND userid=290;
decimal sumLineTotal = (from od in account
where name == 'stocks' && userid == 290
select Balance).Sum();
var sum = db.account.Where(a => a.name == "stocks" && a.userid == 290)
.Sum(a => a.Balance);
Like this:
myBalanceSum = account.Where(x => x.name == 'stocks' && x.userid == 290 ).Sum(x => x.Balance);