EntityFrameWorkCore 学习
实现N个表左连接
var result = this.dbContext.Orders
.GroupJoin(
this.dbContext.Customers
.Where(c => !c.MarkedAsDeleted), // 过滤掉被标记为删除的客户
order => order.Code, // 主表的连接键
customer => customer.Code, // 从表的连接键
(order, customers) => new // 结果选择
{
Order = order,
Customers = customers.ToList() // 获取客户列表
})
.SelectMany(
x => this.dbContext.Products
.Where(p => p.OrderCode == x.Order.Code)
.Select(p => new { Product = p })
.DefaultIfEmpty(), // 实现左连接
(x, product) => new
{
Order = x.Order,
Customers = x.Customers,
Products = product.Product == null ? new List<Product>() : new List<Product> { product.Product } // 避免 null
})
.SelectMany(
x => this.dbContext.Reviews
.Where(r => r.OrderCode == x.Order.Code)
.Select(r => new { Review = r })
.DefaultIfEmpty(), // 实现左连接
(x, review) => new
{
Order = x.Order,
Customers = x.Customers,
Products = x.Products,
Reviews = review.Review == null ? new List<Review>() : new List<Review> { review.Review } // 避免 null
})
.ToList();
解释
-
第一次
GroupJoin
:- 将
Order
和Customer
实体进行左连接,得到每个Order
对象和对应的Customers
列表。
- 将
-
第一次
SelectMany
:- 对第一个左连接结果进行二次左连接,连接到
Product
实体。通过Select(p => new { Product = p })
确保结果类型一致,并在DefaultIfEmpty()
后处理Product
可能为 null 的情况。
- 对第一个左连接结果进行二次左连接,连接到
-
第二次
SelectMany
:- 对包含
Order
、Customers
和Products
的结果进行第三次左连接,连接到Review
实体。通过Select(r => new { Review = r })
确保结果类型一致,并在DefaultIfEmpty()
后处理Review
可能为 null 的情况。
- 对包含
-
处理 null:
Products
和Reviews
可能为空,因此我们用new List<Product>()
和new List<Review>()
替代了null
。