dotnetcore / dotnetcore/FreeSql
希望导航属性 OneToMany 也支持 LEFT JOIN 而不是查询两次
- Dominant language
- C#
- Stars
- 4.4k
- Forks
- 910
- PR merge metrics
- No merged PRs in 30d
Description
#### Feature 特性
```c#
导航属性 OneToMany 支持 LEFT JOIN,只使用一个 SQL 语句查询完再进行分割,而不是查询两次
```
#### 简要描述原因
例如主订单 Order LEFT JOIN 多个子订单 SubOrder 的场景,要区分的话算是 OneToMany,但希望只使用一个 SQL 语句查询完再进行分割(而不是查询两次:先查询主表、再查询子表)。
例如 Dapper 可以用 LEFT JOIN 把主表和子表都绑定到 DTO 上,子表记录使用第二个参数进行 map,然后用 System.Linq.GroupBy(主表字段) 选出主表记录:
```c#
// 类似 Dapper LEFT JOIN + splitOn
var ordersWithSubOrders = connection.Query(
@"SELECT o.*, so.* FROM Orders o
LEFT JOIN SubOrders so ON o.Id = so.OrderId",
(order, subOrder) =>
{
if (order.SubOrders == null) order.SubOrders = new List();
order.SubOrders.Add(subOrder);
return order;
},
splitOn: "OrderId")
.GroupBy(o => o.Id)
.Select(g => g.First())
.ToList();
```
#### 使用场景
已经在简要描述原因中说明。
这种场景不是 ManyToOne 的原因是:并不是先查询子订单记录,然后通过 Parent 去定位主订单,而是反过来:查询主订单的同时,也返回所有子订单。
当然,这种场景下 LEFT JOIN 返回并拆分的模型只支持 SELECT,不支持级联更新和删除。
另外,我也理解,可以像 Dapper 那样先自行 LEFT JOIN 并输出所有实体,然后自己 GroupBy。
```C#
var data = fsql.Select()
.LeftJoin((a,b,c) => a.CategoryId == b.Id)
.LeftJoin((a,b,c) => b.ParentId == c.Id)
.Where((a,b,c) => c.Id > 0)
.ToList((a,b,c) => new { a,b,c });
// data.GroupBy(x => x.a.CategoryId).Select(g => ...);
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.