I have written some LINQ to simulate an SQL GroupBy statement (see below). However, I also need to only consider only the last 10 settingIds before doing my group by. I think I would use Take to do this, but what would be the correct syntax in my statement?
var settings2 = from s in dc.SystemSettings
where s.campConfig.campaignType == campType
&& s.campId != campId
&& s.settingKey == ticket.setting.Key
orderby s.settingId descending
group s by s.settingValue
into grp
select new
{
SettingValue = grp.Key,
SettingCount = grp.Select(x => x.settingValue).Count()
};
I would do something like this
var settings2 = from sOuter in
(from s in dc.SystemSettings
where s.campConfig.campaignType == campType
&& s.campId != campId
&& s.settingKey == ticket.setting.Key
orderby s.settingId descending
select s).Take(10)
group sOuter by sOuter.settingValue
into grp
select new
{
SettingValue = grp.Key,
SettingCount = grp.Select(x => x.settingValue).Count()
};
Related
i have a linq query but in where clause is conditional. if eve.EventType is null then it will not include in where clause. How can we do with Linq lambda expression
var data= (from reg in product
join se in _order on reg.EventSessionId equals se.EventSessionId
join eve in Event on se.EventId equals eve.EventId
where eve.EventType == (EventType)eventType &&
((!string.IsNullOrEmpty(eve.EventName) && eve.EventName.Contains(SearchText, StringComparison.OrdinalIgnoreCase))
select (new OrderHistory
{
RegistrationId = reg.RegistrationId,
EventName = eve.EventName,
EventSesionName = se.EventSesionName,
})).ToList();
Thanks
This may help you.You should check null at first of your expression.
var data= (from reg in product
join se in _order on reg.EventSessionId equals se.EventSessionId
join eve in Event on se.EventId equals eve.EventId
where eve.EventType != null && eve.EventType == (EventType)eventType &&
((!string.IsNullOrEmpty(eve.EventName) && eve.EventName.Contains(SearchText, StringComparison.OrdinalIgnoreCase))
select (new OrderHistory
{
RegistrationId = reg.RegistrationId,
EventName = eve.EventName,
EventSesionName = se.EventSesionName,
})).ToList();
var loggedInHours = db.LoginLogs.Where(l => l.UserId == u.Id && l.UserSessionStop != null)
.Sum(ls=> ls.UserSessionStart.Subtract(ls.UserSessionStop.Value).Hours)
I am trying to calculate Total LoggedIn Hours using this linq query..
But its giving me this error
"Only one expression can be specified in the select list when the subquery is not introduced with EXISTS."
I don't know whats wrong with it..plz help
Try if this works:
var loggedInHours = db.LoginLogs.Where(l => l.UserId == u.Id && l.UserSessionStop != null)
.Select(l=> new {
StartTime = l.UserSessionStart,
EndTime = l.UserSessionStop
})
.ToList()
.Sum(c=> c.StartTime - c.EndTime);
btw, Is UserSessionStop nullable? If yes, then what will be the value to be subtracted?
I would like to create a single query that "adjusts" it's where clause based on a tuple. The first item in the tuple contains a enum value indicating the field in which to filter. The second tuple item is the filter value.
Notice the query below does not work:
var query = from p in db.Categories
where ( QueryBy.Item1 == CategoryFields.Name && p.Name == (string)(QueryBy.Item2) ) ||
( QueryBy.Item1 == CategoryFields.Id && p.Id == (long)(QueryBy.Item2) ) ||
( QueryBy.Item1 == CategoryFields.Description && p.Description == (string)(QueryBy.Item2) ) ||
( QueryBy.Item1 == CategoryFields.SortOrder && p.SortOrder == (int)(QueryBy.Item2) )
select...
if (query.Count() == 1) // ERRORS HERE CONVERSION OF INT
A similar query with only this where clause change will works:
var query = from p in db.Categories
where ( QueryBy.Item1 == CategoryFields.Name && p.Name == (string)(QueryBy.Item2) )
select...
if (query.Count() == 1) // Works HERE
Any idea what could be wrong? Can it be that LINQ where clause perform a short-circuit evaluation and thus the cast of item2 fails? Is there a better way to accomplish my overall goal of adjusting where clause?
Thanks in advance for your help!
LINQ to SQL isn't smart enough to optimize your query and generate it dynamically based on the value of your QueryBy.Item1. It will simply generate a SQL query let SQL server decide this for itself.
When you know that, the error makes sense, since it's impossible for one single value to be castable to both int, long, and string.
In your case you would be better of dynamically generating the right where clause. You can do this with the PredicateBuilder:
IQueryable<Category> query = db.Categories;
var whereClause = PredicateBuilder.False<Category>();
switch (QueryBy.Item1)
{
case CategoryFields.Name:
long id = (string)QueryBy.Item2;
whereClause = whereClause.Or(p => p.Name == name);
break;
case CategoryFields.Id:
string name = (string)QueryBy.Item2;
whereClause = whereClause.Or(p => p.Id == id);
break;
case CategoryFields.Description:
string des = (string)QueryBy.Item2;
whereClause =
whereClause.Or(p => p.Description == des);
break;
case CategoryFields.Id:
string sort = (int)QueryBy.Item2;
whereClause =
whereClause.Or(p => p.SortOrder == sort);
break;
}
query = query.Where(whereClause);
I have this:
var q = (from order in db.Orders
from payment in db.Payments
.Where(x => x.ID == order.paymentID)
.DefaultIfEmpty()
from siteUser in db.SiteUsers
.Where(x => x.siteUserID == order.siteUserID)
.DefaultIfEmpty()
where siteUser.siteUserID != null
select new
{
order.orderID,
order.dateCreated,
payment.totalAmount,
siteUser.firstName,
siteUser.lastName
});
I want to add on to it like this:
switch (_qs["sort"])
{
case "0":
q = q.OrderByDescending(x => x.dateCreated);
break;
case "1":
q = q.OrderBy(x => x.dateCreated);
break; ...
I've done this before with a single table, but the multiple tables in the first code block force me to specify a select statement which causes it to be an anonymous type. How can this be done?
Note: I even tried to make a class with the properties that i'm selecting and casting the query to this type, still a no go.
Not sure I understand the question but the code you pasted looks valid to me.
I checked:
var q = (
from order in db.Orders
join payment in db.Payments on
order.paymentID equals payment.ID into payments
from payment in payments.DefaultIfEmpty()
join siteUser in db.SiteUsers on
order.siteUserID equals siteUser.siteUserID into siteUsers
from siteUser in siteUsers.DefaultIfEmpty()
where siteUser.siteUserID != null
select
new
{
order.orderID,
order.dateCreated,
payment.totalAmount,
siteUser.firstName,
siteUser.lastName
});
switch (sort)
{
case "0":
q = q.OrderByDescending(x => x.dateCreated);
break;
case "1":
q = q.OrderBy(x => x.dateCreated);
break;
}
var restult = q.ToList();
This works.
Just began to develop using LINQ, and still can't understand some simple things.
So,
LinqTable.SingleOrDefault(t=>(t.Field1=="value1")) is equal to SQL "SELECT * FROM LinqTable WHERE Field1="value1" LIMIT 1"
How to create (using Linq) the query like "SELECT * FROM LinqTable WHERE Field1="value1" AND Field2="value2" LIMIT 1?
SingleOrDefault(t=>(t.Field1=="value1" && t.Field2=="value2"))
LinqTable.Where(row => row.Field1 == "value1" && row.Field2 == "value2").FirstOrDefault();
Normally, you'd want to use Where to do this:
var result = LinqTable.Where(t => t.Field1 == "value1" && t.Field2 == "value2").SingleOrDefault();
You can do this directly in the SingleOrDefault line as well:
var result = LinqTable.SingleOrDefault(t => t.Field1 == "value1" && t.Field2 == "value2");