How would you translate this query:
var groups = visibleDateRange.select((date, index) => new { Date = date, Index = index })
.GroupBy(p => p.Index / 3);
to a javascript linqJS query?
All the linqJS samples are super simple... no real life stuff.
My problem is how can I return the anonymous object with Date + Index from the select?
var groups = Enumerable.From(visibleDateRange)
.Select("date, index => { Date: date, Index: index }")
.GroupBy("p => p.Index / 3")
.ToArray();
I used the lambda syntax to define the selectors but you can certainly use regular javascript functions and whatnot.
What you want to get from this is that what you return in your functions is just regular javascript. You're returning an anonymous object with Date and Index members, you create a javascript object with Date and Index members. It's not too different.
Related
In the code below I want to replace x.BaseSalary with any other property whose name is stored in feildtoretrive:
var feildtoretrive = "BaseSalary"
var groupcal = db.Employees.GroupBy(x=>x.Region)
.Select(group => new {
Key = group.Key,
Avg = group.Average(x => x.BaseSalary)
})
.ToList();
You need to
create a MemberExpression that accesses that member of an instance
compile a lambda expression that returns that member for a passed instance parameter
(I assume that the elements in Employees are of type Employee)
// the parameter expression for the lambda (your 'x')
var parameter = Expression.Parameter(typeof(Employee));
// the property access expression (your 'x.BaseSalary' or 'x.<feildtoretrive')
var propAccess = Expression.PropertyOrField(parameter, feildtoretrive);
// the build-together and compiled lambda
var expression = (Expression<Func<Employee, int?>>)Expression.Lambda(propAccess, parameter);
You can now use lambda for the x.Average call:
new { Key = group.Key, Avg = group.Average(lambda) }
A caveat: This only works now for members of type int?. I'm lacking a little experience on how to do this more type independent, but what types can you calculate an average over? But if there are int or double members, another cast expression maybe necessary.
EDIT: (changed the return type to int?). According to Ivan Stoev's comment on my follow up question you could try this:
new { Key = group.Key, Avg = group.AsQueryable().Average(expression) }
EF6 should recognize the call to AsQueryable() and then use the correct Average method (note that I use the expression as argument instead of the lambda). EF Core and linq2Sql won't work with that.
Well I've got a query
var grouped = from a in query
group a.Payment by a.PaymentRecieverId
into g
select g;
query is a IQueryable of new { Payment payment, int PaymentRecieverId }
How can I convert this method expression to query?
If I understand correctly, the question is how to map group a.Payment part.
The GroupBy method has several overloads, you need the one that allows you to specify elementSelector:
var grouped = query.GroupBy(a => a.PaymentRecieverId, a => a.Payment);
If you mean lambda syntax, then it will be:
var grouped = query.GroupBy(x => x.PaymentRecieverId);
If you mean SQL query, then just hover your mouse on query object while debugging:
Trying to add a second where clause to a linq expression but it won't register.
var query = _dbSetBookedResource.AsQueryable<Resource>();
var resources = (from Resource in query where Resource.DateFrom == date select Resource)
if(true)
{
resources.Where(b => b.MemberId == currentUserId);
}
For some reason the second where clause won't register.
For some reason the second where clause won't register.
That's because you're not using the return value anywhere. That's just setting up a query, but then ignoring it. No LINQ methods change the value they're called on - instead they create a new query which has the appropriate filtering, projection etc.
You need:
resources = resources.Where(b => b.MemberId == currentUserId);
Also note that your initial query could be written more simply as:
var resources = query.Where(r => r.DateFrom == date);
Query expressions are overkill when all you want is a simple filter or projection.
I have a Lambda where expression which filters a list of customer based on a ID passed in. This works fine however I want to remove the timestamp from the CreationDate field when I return the records. Is there anyway to do this within the Lambda expression?
So this is my Lambda expression which returns my customer records:
customers = customers.Where(c => c.Business_Type == businessType);
However I'd like to do something like the following:
customers = customers.Where(c => c.Business_Type == businessType, c.CreationDate=c.CreationDate.Value.ToShortDateString());
LINQ is not meant to perform mutation of sequence elements. Just take the return value of Where and use foreach to perform the mutation, which is the idiomatic way to handle this:
var customers = customers.Where(c => c.Business_Type == businessType).ToArray();
foreach(var c in customers)
{
c.CreationDate = c.CreationDate.Value.ToShortDateString();
}
Let's say I have a table in a database that has three columns: Agency ID, Name, and Value.
I want to get a collection of <Name, Value> pairs grouped by Agency ID.
How can I do this? I tried something like below, which works, but makes a DB call for each agency!
from div in db.AgencyDivisionsENT
group div by div.AgencyId into NamePairCollection
select new KeyValuePair<int, IEnumerable<DivisionResults>>(NamePairCollection.Key,
NamePairCollection.Select(k => new DivisionResults
{
Name = k.Name,
Value = k.Value
));
I want to end up with something like this: IEnumerable<KeyValuePair<int, IEnumerable<NameValuePair>>>
Using chain syntax it would be:
db.AgencyDivisionsENT
.GroupBy(x=>x.AgencyId)
.ToDictionary(x=>x.Key, g=>g.Select(x=>new { k.Name, k.Value }).ToArray());
The easiest way to avoid round-tripping with this type of query is to group on the client side - by calling .AsEnumerable():
db.AgencyDivisionsENT
.Select (x => new { x.AgencyId, x.Name, x.Value } )
.AsEnumerable()
.GroupBy(...) // AsEnumerable() forces grouping to happen on the client
.ToDictionary(...)
This is in no way inefficient - as long as:
you select only the data you need from the server with the initial .Select statement
if you need .Where statement to filter the data, it is placed before the .AsEnumerable
you're selecting detail rows (as in this case) rather than just aggregates.