SqlSugar不依赖数据库外键,只要配置实体导航就能使用
long的主键会用雪花ID自动填充 一定要设置WORKID , 只要静态变量不能共享的情况都要有独的WorkId
比如我本地插入和服务上插入那么在同一时间可能会有重复
比如我负载多个服务器时候
SnowFlakeSingle.WorkId= 唯一数字; //从配置文件读取一定要不一样 //在程序启动时设置一次就行
设计参考于EF Core查询,只要配置好实体就可以随意使用导航进行插入操作
//说明: 一对一 、一对多和多对多都可以混合使用 //list里面是多层级的对象 List<Student> list=new List<Student>(); list.Add(new Student(){ Id=0, Name="jack", SchoolId=0, SchoolA=new SchoolA(){...RoomList=new List<Room>{...}}, Books=new List<Books> {...} }) db.InsertNav(list) .Include(z1 => z1.SchoolA).ThenInclude(z1 => z1.RoomList) //插入2层 Root->ShoolA->RoomList .Include(z1 => z1.Books)//插入1层 Root->Books .ExecuteCommand(); //这种表示多层级 //Include(..).ThenInclude(..).ThenInclude(..)
主键自增性能最差,因为自增需要循环才能拿到(多对多中间表除外)
如果是自增建议小数据插入
逻辑插入主表 ,子表存在不插入,不存在插入
//实体 public class StudentA { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int StudentId { get; set; } public string Name { get; set; } public int SchoolId { get; set; } //标准配置 推荐 [Navigate(NavigateType.OneToOne, nameof(SchoolId))]//一对一 SchoolId是StudentA类里面的 public SchoolA SchoolA { get; set; } //不能赋值只能是null //非主键模式 需要手动赋值防止插入0这种默认值 //[Navigate(NavigateType.OneToOne, nameof(SchoolId),nameof(SchoolA.Id))] } public class SchoolA { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id{ get; set; } public string SchoolName { get; set; } } //逻辑插入主表 ,子表存在不插入,不存在插入 var List<StudentA> list=new List<StudentA>(){....}; db.InsertNav(List<StudentA>) .Include(z1 => z1.SchoolA) .ExecuteCommand();
//实体 public class StudentA { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id{ get; set; } public string Name { get; set; } public int SchoolId { get; set; } [Navigate(NavigateType.OneToMany, nameof(BookA.studenId))]//BookA表中的studenId public List<BookA> Books { get; set; }//注意禁止给books手动赋值 //非主键模式 需要手动赋值防止插入0这种默认值 //[Navigate(NavigateType.OneToMany, nameof(BookA.studenId),nameof(Id))] //与一对一相反 第一个 从表字段,第二个主表字段 } public class BookA { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int BookId { get; set; } public string Name { get; set; } public int studenId { get; set; } }
逻辑有2种
//不存在插入主表,强制插入子表 var List<StudentA> list=new List<StudentA>(){....}; db.InsertNav(list) .Include(z1 => z1.Books) .ExecuteCommand(); //5.1.1 preview13 //不存在插入主表,子表存在不插入,不存在插入 var result = db.InsertNav(country) .Include(it =>it.Provinces,new InsertNavOptions() {OneToManyIfExistsNoInsert=true })//配置存在不插入 .ExecuteCommand();//用例代码 //例如Items下面有 lefts和 rights 这个时候第二个Items 需要添加存在不插入,不然插入重复 db.InsertNav(main) .Include(it => it.Items) .ThenInclude(it => it.Lefts) .Include(it => it.Items,new InsertNavOptions(){OneToManyIfExistsNoInsert=true }) .ThenInclude(it => it.Rights) .ExecuteCommand();
主表不存在插入, 子表不存在插入 ,插入关系表(默认会清空中间表,下面配置支持不清空中间表)
db.InsertNav(list) .Include(x => x.Roles, new InsertNavOptions() { ManyToManyNoDeleteMap = true//禁止清空中间表 新功能5.1.3.29-preview01 }).ExecuteCommand();
//实体 public class ABMapping1 { [SugarColumn(IsPrimaryKey = true)]//中间表可以不是主键 public int AId { get; set; } [SugarColumn(IsPrimaryKey = true)]//中间表可以不是主键 public int BId { get; set; } } public class A1 { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id { get; set; } public string Name { get; set; } [Navigate(typeof(ABMapping1), nameof(ABMapping1.AId), nameof(ABMapping1.BId))]//注意顺序 public List<B1> BList { get; set; }//只能是null不能赋默认值 } public class B1 { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id { get; set; } public string Name { get; set; } [Navigat(typeof(ABMapping1), nameof(ABMapping1.BId), nameof(ABMapping1.AId))]//注意顺序 public List<A1> AList { get; set; }//只能是null不能赋默认值 } //主表不存在插入,子表不存在插入,插入关系表 List<A1> List=new List<A1>{ new A1(){ Id=1,BList=new List<B1>{...}} }; db.InsertNav(list) .Include(z1 => z1.BList) .ExecuteCommand(); //小技巧: 如果A和B主键存在可以只传主键,存在只用到主键不需要插入操作
假设Opt 为A表 ,Roles为B表 ,OptRole为中间表 请升级:5.1.4.86
db.InsertNav(Opt).Include(z => z.Roles, new InsertNavOptions() { //设置中间表其他字段 (5.1.4.86) ManyToManySaveMappingTemplate = new OptRole() { CreateTime = "1010",//除了主键和Aid和Bid外的字段赋值 OrgId = "1x" } }) .ExecuteCommand();
db.InsertNav(list,new InsertNavRootOptions() { IgnoreColumns = new string[] { "Id" }//InsertColumns也可以用只插入哪几列 }) .Include(x => x.Roles).ExecuteCommand();
导航更新: https://www.donet5.com/home/Doc?typeId=2432
导航删除: https://www.donet5.com/home/Doc?typeId=2431
导航插入: https://www.donet5.com/home/Doc?typeId=2430
导航查询: https://www.donet5.com/home/Doc?typeId=1188
导航插入默认是自带的雪花ID,如果和你的代码中的雪花ID冲突了可以全部替换成你的雪花ID
//程序启动时执行一次就行 StaticConfig.CustomSnowFlakeFunc = () => { return 你的雪花ID方法(); };
新功能:5.1.4.108
支持第2层级的所有导航自动Includes (超过2层的需要用手动导航插入)
db.InsertNav(list).IncludesAllFirstLayer().ExecuteCommand(); db.InsertNav(list).IncludesAllFirstLayer(nameof(类.导航),nameof(类.导航2)).ExecuteCommand();//排除不需要的导航 //3级+2级自动 db.InsertNav(list) .IncludesAllFirstLayer()//自动2级 .IncludeByNameString(nameof(类.导航2)).ThenIncludeByNameString(nameof(类.导航3))//3级 .ExecuteCommand();
看不懂吗?写个例子:
db.InsertNav(list) .Include(z1 => z1.SchoolA).ThenInclude(z1 => z1.RoomList) //插入2层 Root->ShoolA->RoomList .Include(z1 => z1.Books1)//插入1层 Root->Books1 .Include(z1 => z1.Books2)//插入1层 Root->Books2 .Include(z1 => z1.Books3)//插入1层 Root->Books3 .Include(z1 => z1.Books4)//插入1层 Root->Books4 .Include(z1 => z1.Books5)//插入1层 Root->Books5 .ExecuteCommand(); //可以优化成 db.InsertNav(list) .IncludesAllFirstLayer()//自动2级 .IncludeByNameString(nameof(类.SchoolA)).ThenIncludeByNameString(nameof(类.RoomList3))//3级 .ExecuteCommand();
2016 © donet5.comApache Licence 2.0