简体   繁体   English

EF Core - 复杂查询

[英]EF Core - complex query

I have this DB design (ProductCategories is a join table):我有这个数据库设计(ProductCategories 是一个连接表):

图片

I need to query sold products, filter them by date, group by product ID and find all categories for that product.我需要查询已售出的产品,按日期过滤它们,按产品 ID 分组并查找该产品的所有类别。 Plus some other details irrelevant for this question.加上与这个问题无关的其他一些细节。

I have everything working except finding those categories.除了找到这些类别外,我一切正常。

My current working LINQ query looks like this:我当前工作的 LINQ 查询如下所示:

var articles = await _context.PreordersProducts
    .Where(...)
    .GroupBy(p => new { p.Product.Code, p.Product.Id, Sum = p.Product.ProductVariants.Sum(v => v.InitialQuantity) })
    .Select(p => 
    new Article(
        p.Key.Id,
        p.Key.Code,
        p.Key.Sum
    ))
    .ToListAsync();

it gives me this result:它给了我这个结果:

{
    "id": 11111,
    "code": "123-AAA",
    "initialQuantity": 50,
}

and I need to add categories so the result will look like this:我需要添加类别,所以结果将如下所示:

{
    "id": 11111,
    "code": "123-AAA",
    "initialQuantity": 50,
    "categories": [
        {
            "id": 1,
            "name": "category 1"
        },
        {
            "id": 2,
            "name": "category 2"
        },
    ]
}

I had two ideas but neither of them can be translated to SQL.我有两个想法,但都不能翻译成 SQL。

One was adding Categories to GroupBy:一个是将类别添加到 GroupBy:

.GroupBy(p => new
{
    p.Product.Code,
    p.Product.Id,
    Sum = p.Product.ProductVariants.Sum(v => v.InitialQuantity),
    Categories = p.Product.ProductCategories.Select(c => c.Category)
})

Second was adding SelectMany to Select:其次是将 SelectMany 添加到 Select:

.Select(p =>
new
{
    p.Key.Id,
    p.Key.Code,
    p.Key.Sum,
    Categories = p.SelectMany(c => c.Product.ProductCategories.Select(cc => cc.Category))
})

I belive something like this would be possible in SQL, but this is far beyond my SQL knowledge.我相信在 SQL 中可能会发生这样的事情,但这远远超出了我对 SQL 的了解。

So, could you please help me, how to write this in single query?那么,你能帮我吗,如何在单个查询中写这个?

Classes:课程:

public partial class Product
{
    public int Id { get; private set; }
    public string Name { get; private set; }
    public string Code { get; private set; }

    public virtual ICollection<PreorderProduct> PreorderProducts { get; private set; }
    public virtual ICollection<ProductVariant> ProductVariants { get; private set; }
    public virtual ICollection<ProductCategory> ProductCategories { get; private set; }
}

public partial class ProductVariant
{
    public int Id { get; private set; }
    public int ProductId { get; private set; }
    public string Code { get; private set; }
    public int InitialQuantity { get; private set; }

    public virtual Product Product { get; private set; }
    public virtual ICollection<PreorderProduct> PreorderProducts { get; private set; }
}

public partial class PreorderProduct
{
    public int Id { get; private set; }
    public int ProductId { get; private set; }
    public int ProductVariantId { get; private set; }

    public virtual Product Product { get; private set; }
    public virtual ProductVariant ProductVariant { get; private set; }
}

public partial class ProductCategory
{
    public int Id { get; private set; }
    public int ProductId { get; private set; }
    public int CategoryId { get; private set; }

    public virtual Product Product { get; private set; }
    public virtual Category Category { get; private set; }
}

public partial class Category
{
    public int Id { get; private set; }
    public string Name { get; private set; }

    public virtual ICollection<ProductCategory> ProductCategories { get; private set; }
}

I hope I've got the idea我希望我有这个想法

var filtered = _context.PreordersProducts
    .Where(...);

var grouped = 
   from p in filtered
   from v in p.Product.ProductVariants
   group v by new { p.Product.Code, p.Product.Id } into g
   select new 
   {
        g.Key.Id,
        g.Key.Code,
        initialQuantity = g.Sum(x => x.InitialQuantity)
   };

var query = 
  from g in grouped
  select new
  {
     g.Id,
     g.Code,
     g.initialQuantity,
     categories =_context.ProductCategories
        .Where(x => x.ProductId == g.Id)
        .Select(x => new { id = x.Category.Id, name = x.Category.Name })
        .ToList()
  } 
  
var result = await query.ToListAsync();

Use following:使用以下:

          Product _context = new Product();
           var articles = new
           {
               id = _context.Id,
               code = _context.Code,
               intialQuantity = _context.ProductCategories.Count(),
               categories = _context.ProductCategories.Select(x => new { productId = x.Id, id = x.Category.Id, name = x.Category.Name }).ToList()
           };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM