FreeSql 导航属性的联级保存功能

写在前面

FreeSql 一个款 .net 平台下支持 .net framework 4.5+、.net core 2.1+ 的开源 ORM。单元测试超过3100+,正在不断吸引新的开发者,生命不息开发不止。

和 EFCore 一样,我们也有导航对象,支持【OneToOne】(一对一)、【ManyToOne】(多对一)、【OneToMany】(一对多)、【ParentChild】(父子)、【ManyToMany】(多对多),可以约定配置或手工配置实体间的关联,也可以使用 fluent api 设置关联。

联级保存功能可实现保存对象的时候,将其【OneToMany】、【ManyToMany】导航属性集合也一并保存,本文档说明实现的机制防止误用。

机制规则

【一对多】模型下, 保存时可联级保存实体的属性集合。出于使用安全考虑我们没做完整对比,只实现实体属性集合的添加或更新操作,所以不会删除实体属性集合的数据。

完整对比的功能使用起来太危险,试想下面的场景:

  • 保存的时候,实体的属性集合是空的,如何操作?记录全部删除?
  • 保存的时候,由于数据库中记录非常之多,那么只想保存子表的部分数据,或者只需要添加,如何操作?

【多对多】模型下,我们对中间表的保存是完整对比操作,对外部实体的操作只作新增(注意不会更新)

  • 属性集合为空时,删除他们的所有关联数据(中间表)
  • 属性集合不为空时,与数据库存在的关联数据(中间表)完整对比,计算出应该删除和添加的记录

功能开启和关闭

IFreeSql fsql = new FreeSql.FreeSqlBuilder()

    .UseConnectionString(FreeSql.DataType.Sqlite, "Data Source=|DataDirectory|/document22.db;Pooling=true;Max Pool Size=10")

    .UseAutoSyncStructure(true) //自动同步结构到数据库
    .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) //监听SQL命令对象,在执行后
    .Build();

使用 FreeSqlBuilder 创建好的 IFreeSql 对象,联级保存功能,默认是打开的。

全局关闭:

fsql.SetDbContextOptions(opt => opt.EnableAddOrUpdateNavigateList = false);

局部关闭:

var repo = fsql.GetRepository<T>();
repo.DbContextOptions.EnableAddOrUpdateNavigateList = false;

一对多(OneToMany)代码测试

为了方便展示,以下是一个 ParentChild 关系,其实他也是 OneToMany,只不过是自己指向自己。

[Table(Name = "EAUNL_OTMP_CT")]
class CagetoryParent
{
   
    public Guid Id {
    get; set; }
    public string Name {
    get; set; }

    public Guid ParentId {
    get; set; }
    [Navigate("ParentId")]
    public List<CagetoryParent> Childs {
    get; set; }
}

初始化测试数据:

var cts = new[] {
   
    new CagetoryParent
    {
   
        Name = "分类1",
        Childs = new List<CagetoryParent>(new[]
        {
   
            new CagetoryParent {
    Name = "分类1_1" },
            new CagetoryParent {
    Name = "分类1_2" },
            new CagetoryParent {
    Name = "分类1_3" }
        })
    },
    new CagetoryParent
    {
   
        Name = "分类2",
        Childs = new List<CagetoryParent>(new[]
        {
   
            new CagetoryParent {
    Name = "分类2_1" },
            new CagetoryParent {
    Name = "分类2_2" }
        })
    }
};

1、执行批量插入:

var repo = g.sqlite.GetRepository<CagetoryParent>();
repo.Insert(cts)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeSql 是一个开源的 ORM(对象关系映射)框架,可以通过它来实现数据库的联表查询。下面是一个示例代码,展示了如何使用 FreeSql 进行联表查询: ```csharp using FreeSql; using System; public class Order { public int Id { get; set; } public string OrderNo { get; set; } public int CustomerId { get; set; } public Customer Customer { get; set; } } public class Customer { public int Id { get; set; } public string Name { get; set; } } public class Program { static void Main() { // 创建 FreeSql 对象 var fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, "your_connection_string") .Build(); // 联表查询 var orders = fsql.Select<Order>() .Include(o => o.Customer) .ToList(); foreach (var order in orders) { Console.WriteLine($"OrderNo: {order.OrderNo}, CustomerName: {order.Customer.Name}"); } } } ``` 在这个示例中,我们定义了两个实体类 Order 和 Customer,分别表示订单和客户。通过使用 `Include` 方法,可以指定在查询订单时同时加载关联的客户信息。最后,通过遍历查询结果,可以获取到联表查询的结果。 需要注意的是,示例中的连接字符串需要替换为您自己的数据库连接字符串,并且确保已经正确安装了 FreeSql 包。此外,还可以根据实际需求进行更复杂的联表查询,如使用 `LeftJoin`、`RightJoin` 等方法来指定不同类型的连接。 希望以上示例对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值