This is a relatively new area for me. I have two entities: Inquiries and Categories.
Each Inquiry has a category and a property indicating an integer value (called TotalTimeSpent), and each category has multiple inquiries.
What I want to do is generate a view that is grouped by categories while summing all the inquiries in that one category.
My code at the moment is:
var catgroup = db.CATEGORies.GroupBy(i => i.CATNAME).Sum(c => c.)
Obviously each grouping has multiple inquiries in it, so when I am doing the c=> c. it is not bringing back the property that I need to sum with only the group extensions (like FirstOrDefault).
How do I continue from here so I can sum TotalTimeSpent for each inquiry based on the above grouping?
Try this instead:
var catgroup = db.CATEGORies.GroupBy(c => c.CATNAME)
.Select(g => new {
g.Key,
SUM = g.Sum(s => s.Inqueries.Select(t => t.TotalTimeSpent).Sum())
});
Related
I am trying to build a query using asp.net core c#
https://www.reflectionit.nl/blog/2017/paging-in-asp-net-core-mvc-and-entityframework-core
I trying to do a filtering however I need the data from another table which have my unique id
var result = _context.UserRoles.Where(y => y.RoleId.Contains(selectedRoles.Id)); // Retrieve the the userid i have from another table with the selected roleid
var query = _context.Users.Where(x => //I have already tried contains, where join );
If there is a site where i can learn this query please recommend. "Join()" does not work as I am doing paging
a least two solutions (please note that I do not check the identity classes members, so the following is the "spirit" of the solution (you miss the select clauses) ):
var result = _context.UserRoles.
Where(y => selectedRoles.Contains(y.RoleId)).
Select(y => y.User);
or
var result = _context.UserRoles.
Where(y => selectedRoles.Contains(y.RoleId)).
Select(y => y.UserId);
query = _context.Users.
Where(x => result.Contains(x.Id));
That said, assuming that there is no UserRoles table exposed in Identity (v2), you probably want:
userManager.Users.
Where(u => u.Roles.Any(r => selectecRoles.Contains(r.RoleId)));
Up to you to instanciate the userManager.
I have 3 related entities with 1 to many relationships.
Account 1-* Collection 1-* items
Each of these has a many to many relationship with Users, (with join tables AccountManagers , CollectionManagers, ItemManagers)
I'm trying to get a list of Collections for a user if he's in any of the join tables.
I was thinking create 3 expressions and then merge the 3 results at the end and somehow remove duplicates.
It seemed like Lambda expressions are the way to go, but I'm still learning them.
I think the middle one is easier , like
db.Collections.where(C => C.CollectionManagers.UserID == CurrentUserID)
But how would you gather a list of collections from the users account manager and item manager entries?
Thanks in advance
Using LINQ, the Union operator will return only the unique Collection rows, so assembling each category and combining them should work.
For Items, I thought it would be most efficient to find all Items managed by the current user and then find all collections they belong to:
var iCollections = Items.Where(i => i.ItemManagers.Any(im => im.UserId == CurrentUserID)).SelectMany(i => Collections.Where(c => c.Items.Contains(i)));
It is also possible to do this the other way, e.g. find all Collections that contain an Item managed by the current user:
var iCollections = Collections.Where(c => c.Items.Any(i => i.ItemManagers.Any(im => im.UserId == CurrentUserID)));
For Collections, as you pointed out, you just need to find all collections where the current user manages the collection:
var cCollections = Collections.Where(c => c.CollectionManagers.Any(cm => cm.UserId == CurrentUserID));
For Accounts, we find all accounts managed by the current user and then all collections owned by the account:
var aCollections = Accounts.Where(a => a.AccountManagers.Any(am => am.UserId == CurrentUserID)).SelectMany(a => a.Collections);
Then you can Union the results together:
var CurrentUserCollections = iCollections.Union(cCollections).Union(aCollections);
Just starting out with Entity Framework and am trying to work out how you would do something like this....
Say I have the following entities, Customers that have Orders that have OrderLineItems which are linked to Products. I would like to return the name of every customer with a count of the number of times they have ordered a particular product.
I have seen examples of using .Count() but these have always been for the first navigation property i.e. number of orders per customer.
Would appreciate some guidance here.
Something like this should work, where context is your DbContext instance.
It will return an IEnumerable<dynamic>, although obviously you could make a class to hold the results.
// The product to count
var productId = 12345;
context.Customers.Include("Orders.OrderLineItems.Products")
.Select(customer =>
new {
CustomerName = customer.Name,
ProductCount = customer.Orders
.SelectMany(o => o.OrderLineItems)
.SelectMany(i => i.Products.Where(p => p.Id = productId).Count()
});
The Include() extension method is useful, it will make sure that the resulting SQL query joins the relevant tables together - otherwise multiple queries would be executed for each customer (one to get orders, another for line items and a final one for products).
I have a many to many relationship in EF4 with the following entities:
[Student] - [Class] - [Student_Class]
Moreover i have a [School] entity with a FK on [Student].
If i want to have all the Students of my school i do:
context.School.Include("Student")
but if i want to have the 1rst class of my Students in my school ?
context.School.Include("Student").Include("Student_Class").Where(...
i did not manage to make this thing work...
Can you help ?
Also is it more intelligent to write a full Linq select?
Thanks
John
If you want to do a conditional eager load, then you should NOT be using the Include method.
For loading your school object containing only the students that belong to the first class
You can do a Filtered Projection which returns an Anonymous Type object:
var school = context.School
.Where(s => s.SchoolID == 1) // or any other predicate
.Select(s => new
{
School = s,
Students = s.Student.Where(st => st.ClassID == 1)
}).ToList();
Another way would be to Leverage Attach Method which returns EntityObject:
var school = context.School.Where(s => s.SchoolID == 1).First()
var sourceQuery = school.Students.CreateSourceQuery()
.Where(st => st.ClassID == 1);
school.Students.Attach(sourceQuery);
For a more detailed discussion about this, you can also check:
Entity Framework: How to query data in a Navigation property table
I'm quite a newbie in EF, so I'm sorry if my question has been answered before.. I just can't figure out the syntax..
I have two entities, Category & Product, where one category has many products.
I want to get all categories, with only their latest product (it has a date property named timestamp)
I have no idea how to do that. :-/
If possible I'd like to know the syntax of the two ways to write it, both the sql-like syntax, and the C# like syntax, e.g.:
ctx.Categories.Include("Products").ToList()
from c in ctx.Categories.Include("Products")
Thanks!
Here's the SQL-like way:
var categories =
from p in products
group p by p.Category into g
select new { Category = g.TheKey, LatestProduct = g.Max(p => p.TimeStamp) };
This is the Lambda-way (warning, untested):
var categories = products.GroupBy(p => p.Category)
.Select(g => new { Category = g.TheKey,
LatestProduct = g.Max(p => p.TimeStamp)});
A note on Categories.Include("Products"), you don't need this in your example. You use "Include" for eager-loading, so that for example if you had a list of Categories returned from EF, when you do Categories.Product you will get the associated product.
But all you require is a list of categories, and a single product for each one - which is already returned in the above LINQ query, so no need for Include.