我有User
和Product
个实体,其定义如下:
public class User {
Guid Id { get; set; }
Guid ParentId { get; set; }
ICollection<Product> PermittedProducts { get; set; }
ICollection<User> Children { get; set; }
}
public class Product {
int Id { get; set; }
string Name { get; set; }
ICollection<User> PermittedUsers { get; set; }
}
从概念上讲,Product
有PermittedUsers
的集合 - 即可以购买该产品的用户。此外,每个User
都有一个PermittedProducts
的集合,以及一组子用户,他们也拥有自己的PermittedProducts
集合。
我需要通过存储库运行查询以返回产品列表。存储库方法和DTO定义为:
public ICollection<ProductListDto> GetProductsForUser(Guid userId) {
// Linq query here
}
public class ProductListDto {
int Id { get; set; }
string Name { get; set; }
ICollection<User> Users { get; set; }
}
存储库方法需要带一个Guid userId
并为该用户检索PermittedProducts
并为用户的孩子PermittedProducts
。
例如,如果产品可供用户及其两个孩子使用,那么ProductListDto将拥有该用户集合中的所有三个用户。
作为另一个例子,如果某个产品不适用于某个用户,但该产品可供他的孩子使用,那么这也需要返回。
Product
和User
都可用作聚合根,因此我可以使用ProductRepository
或UserRepository
来查询,通过EntityFramework&#39; s { {1}}。
目前我的存储库方法位于DbSet
(但如果查询更简单,可以移至UserRepository
),如下所示:
ProductRepository
我的问题是我无法弄清楚如何编写Linq查询来实现我需要做的事情!
修改
到目前为止,答案并没有解决如何实现对 public ICollection<ProductListDto> GetProductsForUser(Guid userId) {
// Linq query here - Set is the EF DbSet<User>
var products = from u in
Set.Where(x => x.Id == userId) //.... NOT SURE ABOUT THE REST!
}
的投射
答案 0 :(得分:1)
我如何处理这个问题只是从父UserId建立一个Id列表,这将包含Parent UserId及其所有ChildId。然后,我们可以从此列表中选择PermittedUsers包含其中一个Id的产品。您可以在此处获取产品列表。
var childIds = DbContext.Users.Where(x => x.Id == userId).SelectMany(y => y.Children.Select(z => z.Id)).ToList();
childIds.Add(userId);
var products = DbContext.Products.Where(x => x.Users.SelectMany(y => childIds.Contains(y.Id))).ToList();
答案 1 :(得分:0)
试试这个
userRepository.Where(u => u.Id == userId && u.ParentId == userId)
.SelectMany(u => u.PermittedProducts)
.GroupBy(p => p.Id)
.Select(u => u.First());
线路说明 - 1)检索目标用户及其子女 - 2)从第一行的用户集合中选择所有产品 - 3-4)删除重复项。
注意这样的linq可以被翻译成可以降低性能的重sql查询。也许最好在行(1,2或3)之后调用ToList。还可以编写自己的SQL查询,将它们存储在sql server中,并按名称从代码中调用它们。