C# EF核心-复杂查询
我有这个DB设计(ProductCategories是一个联接表): 我需要查询已售出的产品,按日期筛选,按产品ID分组,并查找该产品的所有类别。还有一些与这个问题无关的细节 除了找到那些类别,我什么都做得很好 我当前正在使用的LINQ查询如下所示:C# EF核心-复杂查询,c#,linq,entity-framework-core,C#,Linq,Entity Framework Core,我有这个DB设计(ProductCategories是一个联接表): 我需要查询已售出的产品,按日期筛选,按产品ID分组,并查找该产品的所有类别。还有一些与这个问题无关的细节 除了找到那些类别,我什么都做得很好 我当前正在使用的LINQ查询如下所示: var articles = await _context.PreordersProducts .Where(...) .GroupBy(p => new { p.Product.Code, p.Product.Id, Su
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();
{
"id": 11111,
"code": "123-AAA",
"initialQuantity": 50,
"categories": [
{
"id": 1,
"name": "category 1"
},
{
"id": 2,
"name": "category 2"
},
]
}
它给了我这个结果:
{
"id": 11111,
"code": "123-AAA",
"initialQuantity": 50,
}
我需要添加类别,结果如下所示:
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();
{
"id": 11111,
"code": "123-AAA",
"initialQuantity": 50,
"categories": [
{
"id": 1,
"name": "category 1"
},
{
"id": 2,
"name": "category 2"
},
]
}
我有两个想法,但都不能翻译成SQL
一个是向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)
})
第二个是添加SelectMany以进行选择:
.Select(p =>
new
{
p.Key.Id,
p.Key.Code,
p.Key.Sum,
Categories = p.SelectMany(c => c.Product.ProductCategories.Select(cc => cc.Category))
})
我相信这样的事情在SQL中是可能的,但这远远超出了我的SQL知识范围
那么,你能帮助我,如何在单个查询中编写这个吗
课程:
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; }
}
公共部分类乘积
{
public int Id{get;private set;}
公共字符串名称{get;private set;}
公共字符串代码{get;private set;}
公共虚拟ICollection预订单产品{get;private set;}
公共虚拟ICollection产品变量{get;private set;}
公共虚拟ICollection ProductCategories{get;private set;}
}
公共部分类ProductVariant
{
public int Id{get;private set;}
public int ProductId{get;private set;}
公共字符串代码{get;private set;}
public int InitialQuantity{get;private set;}
公共虚拟产品产品{get;private set;}
公共虚拟ICollection预订单产品{get;private set;}
}
公共部分类预订单产品
{
public int Id{get;private set;}
public int ProductId{get;private set;}
public int productVariatid{get;private set;}
公共虚拟产品产品{get;private set;}
公共虚拟ProductVariant ProductVariant{get;private set;}
}
公共部分类ProductCategory
{
public int Id{get;private set;}
public int ProductId{get;private set;}
public int CategoryId{get;private set;}
公共虚拟产品产品{get;private set;}
公共虚拟类别{get;私有集;}
}
公共部分类
{
public int Id{get;private set;}
公共字符串名称{get;private set;}
公共虚拟ICollection ProductCategories{get;private set;}
}
使用以下内容:
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()
};
我希望我有这个想法
var filtered=\u context.PreordersProducts
.其中(…);
变量分组=
从p开始过滤
从p.Product.ProductVariants中的v开始
按新的{p.Product.Code,p.Product.Id}将v组划分为g组
选择新的
{
g、 密钥Id,
g、 密码,
initialQuantity=g.Sum(x=>x.initialQuantity)
};
变量查询=
从g开始分组
选择新的
{
g、 身份证,
g、 代码,
g、 初始数量,
categories=\u context.ProductCategories
.其中(x=>x.ProductId==g.Id)
.Select(x=>new{id=x.Category.id,name=x.Category.name})
托利斯先生()
}
var result=wait query.ToListAsync();
我能说什么,查询是错误的。用类更新问题,而不是图片。@SvyatoslavDanyliv完成。谢谢,但可能您误解了一点_上下文是EF的DbContext,而不是产品。我查询预订单产品,然后按ProductID对它们进行分组。例如,它给了我10种产品。最后,我需要对所有这些产品进行分类。结果就是产品列表,每个产品都有一个类别列表。希望是一个查询。太好了,太棒了,谢谢!我不知道我可以在查询中第二次使用上下文。这些信息现在让我做很多事情变得更容易。为什么不呢,它是一个源表-查询的片段。