Skip to content

指定层级自动加载导航属性,并支持根据从表条件过滤主表数据 #1113

Closed
@hd2y

Description

@hd2y

目前有个项目基于 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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions