披露:我是RDO.Net的作者。
是的。我相信现有的 ORM 正朝着错误的方向发展——他们试图将关系数据映射到任意对象中,恕我直言,这是不可能的。在 OO 世界中,任意对象不是序列化/反序列化友好的,因为每个对象都有一个当前进程本地的对象引用(地址)。处理单个对象没问题,遇到复杂对象图就麻烦了。
希望这个问题可以使用不同的方法来解决,如RDO.Net:我们不是将关系数据映射到任意对象,而是将数据的模式映射为丰富的元数据(Model 包含列,主要/外部密钥、验证等),并公开具体的Db、DbTable、DbQuery 和DataSet 以进行数据访问。执行数据库 CRUD 操作时,您可以使用强类型 OO 语言显式构建 SQL 抽象语法树 (AST),如以下示例 C# 代码所示,该代码创建查询并返回分层数据的 DataSet:
public async Task<DataSet<SalesOrderInfo>> GetSalesOrderInfoAsync(_Int32 salesOrderID, CancellationToken ct = default(CancellationToken))
{
var result = CreateQuery((DbQueryBuilder builder, SalesOrderInfo _) =>
{
builder.From(SalesOrderHeader, out var o)
.LeftJoin(Customer, o.FK_Customer, out var c)
.LeftJoin(Address, o.FK_ShipToAddress, out var shipTo)
.LeftJoin(Address, o.FK_BillToAddress, out var billTo)
.AutoSelect()
.AutoSelect(c, _.Customer)
.AutoSelect(shipTo, _.ShipToAddress)
.AutoSelect(billTo, _.BillToAddress)
.Where(o.SalesOrderID == salesOrderID);
});
await result.CreateChildAsync(_ => _.SalesOrderDetails, (DbQueryBuilder builder, SalesOrderInfoDetail _) =>
{
builder.From(SalesOrderDetail, out var d)
.LeftJoin(Product, d.FK_Product, out var p)
.AutoSelect()
.AutoSelect(p, _.Product)
.OrderBy(d.SalesOrderDetailID);
}, ct);
return await result.ToDataSetAsync(ct);
}