Closed
Description
目前有个项目基于 Dapper 以及 EF 拓展开发,查询时支持指定层级对导航属性进行贪婪加载,并且前端支持通过 [Key, Condition]
的方式自从表开始过滤数据,不知道现在有没有好的实现方案。
指定贪婪加载层级
Order(订单) 与 Orgnization(组织) 一对一
Order(订单) 与 OrderItem(订单行记录) 一对多
OrderItem(订单行记录) 与 Material(物料) 一对一
Material(物料) 与 Unit(单位) 一对多
以下为模拟测试数据,为实现加载单据下从表数据,需要一直向下追加 Include
/IncludeMany
,并且当碰到从表是一对一关系无法继续向下加载从表数据。
当前项目实现的效果是比如 InludeLevel(int level)
,填写 3 后,上述会查询到 Unit 这一层。2 则会查询到仅 Material 这一层。
void Main()
{
IFreeSql freeSql = new FreeSqlBuilder()
.UseConnectionString(DataType.Sqlite, "Data Source=:memory:;")
.UseAutoSyncStructure(true)
.Build();
freeSql.Aop.CurdBefore += (s, e) =>
{
e.Sql.Dump();
};
var orgnization = new Orgnization { Code = "C001" };
freeSql.Insert(orgnization).ExecuteAffrows();
var materials = new[]
{
new Material{Code="TEST1",Units=new List<Unit>{new Unit{Code = "KG"}}},
new Material{Code="TEST2",Units=new List<Unit>{new Unit{Code = "KG"}}}
};
var repo1 = freeSql.GetGuidRepository<Material>();
repo1.DbContextOptions.EnableCascadeSave = true;
repo1.Insert(materials);
var order = new Order
{
Code = "X001",
OrgnizationId = orgnization.Id,
OrderItems = new List<OrderItem>
{
new OrderItem{ ItemCode = "01", MaterialId = materials[0].Id },
new OrderItem { ItemCode = "02", MaterialId = materials[1].Id },
}
};
var repo2 = freeSql.GetGuidRepository<Order>();
repo2.DbContextOptions.EnableCascadeSave = true;
repo2.Insert(order);
// 这里不知道该怎么继续加载 Unit
var list = repo2.Where(t => t.Code.StartsWith("X"))
.Include(t => t.Orgnization)
.IncludeMany(t => t.OrderItems, then => then.Include(t2 => t2.Material))
.ToList();
list.Dump();
}
public class Order
{
public Guid Id { get; set; }
public string Code { get; set; }
public Guid OrgnizationId { get; set; }
[Navigate(nameof(OrgnizationId))]
public Orgnization Orgnization { get; set; }
[Navigate(nameof(OrderItem.OrderId))]
public List<OrderItem> OrderItems { get; set; }
}
public class OrderItem
{
public Guid Id { get; set; }
public string ItemCode { get; set; }
public Guid MaterialId { get; set; }
public Guid OrderId { get; set; }
[Navigate(nameof(MaterialId))]
public Material Material { get; set; }
}
public class Orgnization
{
public Guid Id { get; set; }
public string Code { get; set; }
}
public class Material
{
public Guid Id { get; set; }
public string Code { get; set; }
[Navigate(nameof(Unit.MaterialId))]
public List<Unit> Units { get; set; }
}
public class Unit
{
public Guid Id { get; set; }
public string Code { get; set; }
public Guid MaterialId { get; set; }
}
过滤数据
目前,接口还支持通过从表过滤数据,例如查询 Order
时,条件为 ["OrderItems.Material.Code": {"=", "TEST1"}]
,则会查询到所有存在该物料的单据信息。
// 这里不知道该怎么继续加载 Unit
var list1 = repo2.Where(t => t.OrderItems.Any(t => t.Material.Code == "TEST1"))
.Include(t => t.Orgnization)
.IncludeMany(t => t.OrderItems, then => then.Include(t2 => t2.Material))
.ToList();
像这种主从关系的表以及查询业务还有很多,不知道如何迁移到 FreeSql
并实现该这些业务。:cry:
Metadata
Metadata
Assignees
Labels
No labels