Open et2012 opened 2 months ago
这种情况只适合一层级联join,如果多层的情况会导致大量的IO数据冗余。
这种情况只适合一层级联join,如果多层的情况会导致大量的IO数据冗余。
是,我明白。所以我说的这种情况或许不太算是导航属性,而更像是 Dapper 风格、有点 Geek 的自定义查询。 或者说,在满足某些条件(例如你说的只有一层级联)的前提下,添加相关重载或单独 API,允许 OneToMany 也使用 JOIN。
其实现有的 Select
和 LeftJoin
也大致够用了,不过 ToList
目前只支持传入一个 Expression
:(a,b) => new {...}
。
是否有可能传入一个 Func<A, B, TOutput> map
,或增加一个 Fluent API,像 Dapper splitOn 那样自己做映射。
既可以做 OneToMany 映射:
(order, subOrder) => {
order.SubOrders.Add(subOrder);
return order;
}
也可以做 ManyToOne 映射:
(order, subOrder) => {
subOrder.Parent = order;
return subOrder;
}
fsql.Select<Topic, Category, CategoryType>() .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 });
fsql.Select<Topic, Category, CategoryType>() .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 });
我知道这种用法,目前也确实是这样用的。 我提这个 Feature Request 的原因前面也说了,有没有可能让 LEFT JOIN 逻辑在特定条件下也能用到 OneToMany 上。
Feature 特性
简要描述原因
例如主订单 Order LEFT JOIN 多个子订单 SubOrder 的场景,要区分的话算是 OneToMany,但希望只使用一个 SQL 语句查询完再进行分割(而不是查询两次:先查询主表、再查询子表)。
例如 Dapper 可以用 LEFT JOIN 把主表和子表都绑定到 DTO 上,子表记录使用第二个参数进行 map,然后用 System.Linq.GroupBy(主表字段) 选出主表记录:
使用场景
已经在简要描述原因中说明。 这种场景不是 ManyToOne 的原因是:并不是先查询子订单记录,然后通过 Parent 去定位主订单,而是反过来:查询主订单的同时,也返回所有子订单。 当然,这种场景下 LEFT JOIN 返回并拆分的模型只支持 SELECT,不支持级联更新和删除。
另外,我也理解,可以像 Dapper 那样先自行 LEFT JOIN 并输出所有实体,然后自己 GroupBy。