[开源] .Net orm FreeSql 1.5.0 最新版本(番号:好久不见) (4)

我们知道 EFCore for oracle 问题多,并且现在还没更新到 3.x,在这样的背景下,一个国产数据库更不能指望谁实现好用的 EFCore。目前看来除了 EFCore for sqlserver 我们没把握完全占优势,起码在其他数据库肯定是我们更接地气。

言归正传,达梦数据库其实蛮早就支持了,之前是以 Odbc 的方式实现的,后面根据使用者的反馈 Odbc 环境问题比较麻烦,经研究决定支持 ado.net 适配,让使用者更加方便。使用 ado.net 方式连接达梦只需要修改 IFreeSql 创建时候的类型即可,如下:

static IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Dameng, connectionString) .UseAutoSyncStructure(true) //自动同步实体结构到数据库 .Build(); //请务必定义成 Singleton 单例模式 七、兼容 EFCore 实体特性、FluentApi

EFCore 目前用户量最多,为了方便一些项目过渡到 FreeSql,我们做了一些 “AI”:

[开源] .Net orm FreeSql 1.5.0 最新版本(番号:好久不见)

自动识别 EFCore 实体特性:Key/Required/NotMapped/Table/Column

[Table("table01")] //这个其实是 EFCore 的特性 class MyTable { [Key] public int Id { get; set; } }

与 EFCore 90% 相似的 FluentApi

fsql.CodeFirst.Entity<Song>(eb => { eb.ToTable("tb_song"); eb.Ignore(a => a.Field1); eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); eb.Property(a => a.Url).HasMaxLength(100); eb.Property(a => a.RowVersion).IsRowVersion(); eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp"); eb.HasKey(a => a.Id); eb.HasIndex(a => new { a.Id, a.Title }).IsUnique().HasName("idx_xxx11"); //一对多、多对一 eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); //多对多 eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); }); fsql.CodeFirst.Entity<SongType>(eb => { eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); eb.HasData(new[] { new SongType { Id = 1, Name = "流行", Songs = new List<Song>(new[] { new Song{ Title = "真的爱你" }, new Song{ Title = "爱你一万年" }, }) }, new SongType { Id = 2, Name = "乡村", Songs = new List<Song>(new[] { new Song{ Title = "乡里乡亲" }, }) }, }); }); public class SongType { public int Id { get; set; } public string Name { get; set; } public List<Song> Songs { get; set; } } public class Song { [Column(IsIdentity = true)] public int Id { get; set; } public string Title { get; set; } public string Url { get; set; } public DateTime CreateTime { get; set; } public int TypeId { get; set; } public SongType Type { get; set; } public int Field1 { get; set; } public long RowVersion { get; set; } } 八、ISelect.ToTreeList 查询树型数据 List

这是几个意思?有做过父子关系的表应该知道的,把数据查回来了是平面的,需要再用递归转化为树型。考虑到这个功能实用性比较高,所以就集成了进来。来自单元测试的一段代码:

var repo = fsql.GetRepository<VM_District_Child>(); repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; repo.DbContextOptions.NoneParameter = true; repo.Insert(new VM_District_Child { Code = "100000", Name = "中国", Childs = new List<VM_District_Child>(new[] { new VM_District_Child { Code = "110000", Name = "北京市", Childs = new List<VM_District_Child>(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, }) } }) }); var t3 = fsql.Select<VM_District_Child>().ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); Assert.Equal("110000", t3[0].Childs[0].Code); Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code);

注意:实体需要配置父子导航属性

九、BulkCopy 大批量数据

原先 FreeSql 对批量数据操作就做得还可以,例如批量数据超过数据库某些限制的,会拆分执行,性能其实也还行。

本需求也是来自用户,然后就实现了,实现完了我还专门做了性能测试对比,sqlserver bulkcopy 收益比较大,mysql 收益非常小。

测试结果(52个字段,18W-50行数据,单位ms):

18W 1W 5K 500 50
MySql 5.5 ExecuteAffrows   38,481   2,234   1,136   167   30  
MySql 5.5 ExecuteMySqlBulkCopy   28,405   1,142   657   592   22  
SqlServer Express ExecuteAffrows   402,355   24,847   11,465   915   88  
SqlServer Express ExecuteSqlBulkCopy   21,065   578   326   79   48  
PostgreSQL 10 ExecuteAffrows   46,756   3,294   2,269   209   37  
PostgreSQL 10 ExecutePgCopy   10,090   583   337   61   25  
Oracle XE ExecuteAffrows   -   -   -   10,648   200  
Sqlite ExecuteAffrows   28,554   1,149   701   91   35  

Oracle 插入性能不用怀疑,可能安装学生版限制较大

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssygg.html