网站里弹窗怎么做,龙岩建设局网站罗小波,网站开发财务预算,怎么做原创短视频网站废话开头这篇文章是我有史以来编辑最长时间的#xff0c;历时 4小时#xff01;#xff01;#xff01;原本我可以利用这 4小时编写一堆胶水代码#xff0c;真心希望善良的您点个赞#xff0c;谢谢了#xff01;#xff01;很久很久没有写文章了#xff0c;上一次还是… 废话开头这篇文章是我有史以来编辑最长时间的历时 4小时原本我可以利用这 4小时编写一堆胶水代码真心希望善良的您点个赞谢谢了很久很久没有写文章了上一次还是在元旦发布 1.0 版本的时候今年版本规划是每月底发布小版本年底发布 2.0全年的开源工作主要是收集用户需求增加功能完善测试修复 bug。FreeSql 1.0 - 1.5 相隔半年有哪些新功能只能说每个功能都能让我兴奋并且能感受到使用者也一样兴奋妄想症。迫不及待的人会问这更新速度也太快了吧升级会不会有问题不了解版本的更新日志直接升级不是好的习惯建议关注我们的更新日志github 上有专门的文档我们的版本开发原则在尽量保证兼容的情况下增加新功能砍掉少量不合理的功能我们的单元测试数量4000这是我们引以自豪发布版本的保障2|0入戏准备FreeSql 是 .Net ORM能支持 .NetFramework4.0、.NetCore、Xamarin、XAUI、Blazor、以及还有说不出来的运行平台因为代码绿色无依赖支持新平台非常简单。目前单元测试数量4000Nuget下载数量123K源码几乎每天都有提交。值得高兴的是 FreeSql 加入了 ncc 开源社区https://github.com/dotnetcore/FreeSql加入组织之后社区责任感更大需要更努力做好品质为开源社区出一份力。QQ开发群4336577为什么要重复造轮子FreeSql 主要优势在于易用性上基本是开箱即用在不同数据库之间切换兼容性比较好。作者花了大量的时间精力在这个项目肯请您花半小时了解下项目谢谢。FreeSql 整体的功能特性如下支持 CodeFirst 对比结构变化迁移支持 DbFirst 从数据库导入实体类支持 丰富的表达式函数自定义解析支持 批量添加、批量更新、BulkCopy支持 导航属性贪婪加载、延时加载、级联保存支持 读写分离、分表分库租户设计支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/MsAccess1.0 - 1.5 更新的重要功能如下一、UnitOfWorkManager 工作单元管理器可实现 Spring 事务设计二、IFreeSql.InsertOrUpdate 实现批量保存执行时根据数据库自动适配执行 merge into 或者 on duplicate key update三、ISelect.WhereDynamicFilter 方法实现动态过滤条件与前端交互四、自动适配表达式解析 yyyyMMdd 常用 c# 日期格式化五、IUpdate.SetSourceIgnore 方法实现忽略属性值为 null 的字段六、FreeSql.Provider.Dameng 基于 DmProvider Ado.net 访问达梦数据库七、自动识别 EFCore 常用的实体特性FreeSql.DbContext 拥有和 EFCore 高相似度的语法并且支持 90% 相似的 FluentApi八、ISelect.ToTreeList 扩展方法查询数据把配置父子导航属性的实体加工为树型 List九、BulkCopy 相关方法提升大批量数据插入性能十、Sqlite :memrory: 内存模式FreeSql 使用非常简单只需要定义一个 IFreeSql 对象即可static IFreeSql fsql new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, connectionString).UseAutoSyncStructure(true) //自动同步实体结构到数据库.Build(); //请务必定义成 Singleton 单例模式3|0UnitOfWorkManager 工作单元管理器public class SongService
{BaseRepositorySong _repo;public SongService(BaseRepositorySong repo){_repo repo;}[Transactional]public virtual void Test1(){_repo.Insert(new Song { Title 卡农1 }); //事务1this.Test2();}[Transactional(Propagation Propagation.Nested)] //嵌套事务新的不使用 Test1 的事务public virtual void Test2(){_repo.Insert(new Song { Title 卡农2 });}
}BaseRepository 是 FreeSql.BaseRepository 包实现的通用仓储类实际项目中可以继承它再使用。Propagation 的模式参考了 Spring 事务在以下几种模式Requierd如果当前没有事务就新建一个事务如果已存在一个事务中加入到这个事务中默认的选择。Supports支持当前事务如果没有当前事务就以非事务方法执行。Mandatory使用当前事务如果没有当前事务就抛出异常。NotSupported以非事务方式执行操作如果当前存在事务就把当前事务挂起。Never以非事务方式执行操作如果当前事务存在则抛出异常。Nested以嵌套事务方式执行。上面的例子使用的这个UnitOfWorkManager 正是干这件事的。避免了每次对数据操作都要现获得 Session 实例来启动事务/提交/回滚事务还有繁琐的Try/Catch操作。这些也是 AOP面向切面编程机制很好的应用。一方面使开发业务逻辑更清晰、专业分工更加容易进行。另一方面就是应用 AOP 隔离降低了程序的耦合性使我们可以在不同的应用中将各个切面结合起来使用大大提高了代码重用度。使用前准备第一步配置 Startup.cs 注入//Startup.cs
public void ConfigureServices(IServiceCollection services)
{services.AddSingletonIFreeSql(fsql);services.AddScopedUnitOfWorkManager();services.AddFreeRepository(null, typeof(Startup).Assembly);
}
UnitOfWorkManager 成员说明IUnitOfWork Current返回当前的工作单元void Binding(repository)将仓储的事务交给它管理IUnitOfWork Begin(propagation, isolationLevel)创建工作单元使用前准备第二步定义事务特性[AttributeUsage(AttributeTargets.Method)]
public class TransactionalAttribute : Attribute
{/// summary/// 事务传播方式/// /summarypublic Propagation Propagation { get; set; } Propagation.Requierd;/// summary/// 事务隔离级别/// /summarypublic IsolationLevel? IsolationLevel { get; set; }
}
使用前准备第三步引入动态代理库在 Before 从容器中获取 UnitOfWorkManager调用它的 var uow uowManager.Begin(attr.Propagation, attr.IsolationLevel) 方法在 After 调用 Before 中的 uow.Commit 或者 Rollback 方法最后调用 uow.Dispose自问自答是不是进方法就开事务呢不一定是真实事务有可能是虚的就是一个假的 unitofwork不带事务也有可能是延用上一次的事务也有可能是新开事务具体要看传播模式。4|0IFreeSql.InsertOrUpdate 批量插入或更新IFreeSql 定义了 InsertOrUpdate 方法实现批量插入或更新的功能利用的是数据库特性进行保存执行时根据数据库自动适配DatabaseFeaturesMySqlon duplicate key updatePostgreSQLon conflict do updateSqlServermerge intoOraclemerge intoSqlitereplace intoDamengmerge intofsql.InsertOrUpdateT().SetSource(items) //需要操作的数据.ExecuteAffrows();
由于我们前面定义 fsql 变量的类型是 MySql所以执行的语句大概是这样的INSERT INTO T(id, name) VALUES(1, 001), (2, 002), (3, 003), (4, 004)
ON DUPLICATE KEY UPDATE
name VALUES(name)
当实体类有自增属性时批量 InsertOrUpdate 最多可被拆成两次执行内部计算出未设置自增值、和有设置自增值的数据分别执行 insert into 和 上面讲到的 merge into 两种命令采用事务执行。5|0WhereDynamicFilter 动态过滤是否见过这样的高级查询功能WhereDynamicFilter 在后端可以轻松完成这件事情前端根据 UI 组装好对应的 json 字符串传给后端就行如下DynamicFilterInfo dyfilter JsonConvert.DeserializeObjectDynamicFilterInfo(
{Logic : Or,Filters :[{Field : Code,Operator : NotContains,Value : val1,Filters :[{Field : Name,Operator : NotStartsWith,Value : val2,}]},{Field : Parent.Code,Operator : Eq,Value : val11,Filters :[{Field : Parent.Name,Operator : Contains,Value : val22,}]}]
}
);
fsql.SelectVM_District_Parent().WhereDynamicFilter(dyfilter).ToList();
//SELECT a.Code, a.Name, a.ParentCode, a__Parent.Code as4, a__Parent.Name as5, a__Parent.ParentCode as6
//FROM D_District a
//LEFT JOIN D_District a__Parent ON a__Parent.Code a.ParentCode
//WHERE (not((a.Code) LIKE %val1%) AND not((a.Name) LIKE val2%) OR a__Parent.Code val11 AND (a__Parent.Name) LIKE %val22%)
支持的操作符Contains/StartsWith/EndsWith/NotContains/NotStartsWith/NotEndsWith、Equals/Eq/NotEqual、GreaterThan/GreaterThanOrEqual、LessThan/LessThanOrEqual6|0表达式解析 yyyyMMdd c# 常用日期格式化不知道大家有没有这个困扰在 ORM 表达式使用 DateTime.Now.ToString(yyyyMM) 是件很难转换的事在我适配的这些数据库中只有 MsAccess 可以直接翻译成对应的 SQL 执行。这个想法来自另一个 ORM issues我时不时会去了解其他 ORM 优点和缺陷以便给 FreeSql 做补充。想法出来之后当于也就是昨天 2020/5/24 奋战一宿完成的除了每个数据库进行编码适配外更多的时间耗在了单元测试上目前已全部通过4000单元测试不是吹的。仅以此功能让大家感受一下 FreeSql 的认真他不是一些人口中所说的个人项目谢谢。var dtn DateTime.Parse(2020-1-1 0:0:0);
var dts Enumerable.Range(1, 12).Select(a dtn.AddMonths(a)).Concat(Enumerable.Range(1, 31).Select(a dtn.AddDays(a))).Concat(Enumerable.Range(1, 24).Select(a dtn.AddHours(a))).Concat(Enumerable.Range(1, 60).Select(a dtn.AddMinutes(a))).Concat(Enumerable.Range(1, 60).Select(a dtn.AddSeconds(a)));
foreach (var dt in dts)
{Assert.Equal(dt.ToString(yyyy-MM-dd HH:mm:ss.fff), fsql.SelectT().First(a dt.ToString()));Assert.Equal(dt.ToString(yyyy-MM-dd HH:mm:ss), fsql.SelectT().First(a dt.ToString(yyyy-MM-dd HH:mm:ss)));Assert.Equal(dt.ToString(yyyy-MM-dd HH:mm), fsql.SelectT().First(a dt.ToString(yyyy-MM-dd HH:mm)));Assert.Equal(dt.ToString(yyyy-MM-dd HH), fsql.SelectT().First(a dt.ToString(yyyy-MM-dd HH)));Assert.Equal(dt.ToString(yyyy-MM-dd), fsql.SelectT().First(a dt.ToString(yyyy-MM-dd)));Assert.Equal(dt.ToString(yyyy-MM), fsql.SelectT().First(a dt.ToString(yyyy-MM)));Assert.Equal(dt.ToString(yyyyMMddHHmmss), fsql.SelectT().First(a dt.ToString(yyyyMMddHHmmss)));Assert.Equal(dt.ToString(yyyyMMddHHmm), fsql.SelectT().First(a dt.ToString(yyyyMMddHHmm)));Assert.Equal(dt.ToString(yyyyMMddHH), fsql.SelectT().First(a dt.ToString(yyyyMMddHH)));Assert.Equal(dt.ToString(yyyyMMdd), fsql.SelectT().First(a dt.ToString(yyyyMMdd)));Assert.Equal(dt.ToString(yyyyMM), fsql.SelectT().First(a dt.ToString(yyyyMM)));Assert.Equal(dt.ToString(yyyy), fsql.SelectT().First(a dt.ToString(yyyy)));Assert.Equal(dt.ToString(HH:mm:ss), fsql.SelectT().First(a dt.ToString(HH:mm:ss)));Assert.Equal(dt.ToString(yyyy MM dd HH mm ss yy M d H hh h), fsql.SelectT().First(a dt.ToString(yyyy MM dd HH mm ss yy M d H hh h)));Assert.Equal(dt.ToString(yyyy MM dd HH mm ss yy M d H hh h m s tt t).Replace(上午, AM).Replace(下午, PM).Replace(上, A).Replace(下, P), fsql.SelectT().First(a dt.ToString(yyyy MM dd HH mm ss yy M d H hh h m s tt t)));
}支持常用 c# 日期格式化yyyy MM dd HH mm ss yy M d H hh h m s tt ttt t 为 AM PMAM PM 这两个转换不完美勉强能使用。7|0IUpdate.SetSourceIgnore 不更新 null 字段这个功能被用户提了几次每一次都认为 FreeSql.Repository 的状态对比可以完成这件事。这一次作者心疼他们了为什么一定要用某个功能限制住使用者大家是否经常听谁说 EF框架、MVC框架框架的定义其实是约束规范。作者不想做这样的约束作者更希望尽量提供多一些实用功能让用户自己选择把项目定义为功能组件。fsql.UpdateSong().SetSourceIgnore(item, col col null).ExecuteAffrows();第二个参数是 Funcobject, bool 类型col 相当于属性的值上面的代码更新实体 item 的时候会忽略 null 的属性。8|0Ado.net 访问达梦数据库武汉达梦数据库有限公司成立于2000年为中国电子信息产业集团(CEC)旗下基础软件企业专业从事数据库管理系统的研发、销售与服务同时可为用户提供大数据平台架构咨询、数据技术方案规划、产品部署与实施等服务。多年来达梦公司始终坚持原始创新、独立研发目前已掌握数据管理与数据分析领域的核心前沿技术拥有全部源代码具有完全自主知识产权。不知道大家没有听说过相关政策政府推动国产化以后是趋势虽然 .NET 不是国产但是目前无法限制编程语言当下正在对操作系统、数据库强制推进。我们知道 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 单例模式
9|0兼容 EFCore 实体特性、FluentApiEFCore 目前用户量最多为了方便一些项目过渡到 FreeSql我们做了一些 “AI”自动识别 EFCore 实体特性Key/Required/NotMapped/Table/Column[Table(table01)] //这个其实是 EFCore 的特性
class MyTable
{[Key]public int Id { get; set; }
}
与 EFCore 90% 相似的 FluentApifsql.CodeFirst.EntitySong(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.EntitySongType(eb {eb.HasMany(a a.Songs).WithOne(a a.Type).HasForeignKey(a a.TypeId);eb.HasData(new[]{new SongType{Id 1,Name 流行,Songs new ListSong(new[]{new Song{ Title 真的爱你 },new Song{ Title 爱你一万年 },})},new SongType{Id 2,Name 乡村,Songs new ListSong(new[]{new Song{ Title 乡里乡亲 },})},});
});public class SongType {public int Id { get; set; }public string Name { get; set; }public ListSong 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; }
}
10|0ISelect.ToTreeList 查询树型数据 List这是几个意思有做过父子关系的表应该知道的把数据查回来了是平面的需要再用递归转化为树型。考虑到这个功能实用性比较高所以就集成了进来。来自单元测试的一段代码var repo fsql.GetRepositoryVM_District_Child();
repo.DbContextOptions.EnableAddOrUpdateNavigateList true;
repo.DbContextOptions.NoneParameter true;
repo.Insert(new VM_District_Child
{Code 100000,Name 中国,Childs new ListVM_District_Child(new[] {new VM_District_Child{Code 110000,Name 北京市,Childs new ListVM_District_Child(new[] {new VM_District_Child{ Code110100, Name 北京市 },new VM_District_Child{ Code110101, Name 东城区 },})}})
});
var t3 fsql.SelectVM_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);
注意实体需要配置父子导航属性11|0BulkCopy 大批量数据原先 FreeSql 对批量数据操作就做得还可以例如批量数据超过数据库某些限制的会拆分执行性能其实也还行。本需求也是来自用户然后就实现了实现完了我还专门做了性能测试对比sqlserver bulkcopy 收益比较大mysql 收益非常小。测试结果(52个字段18W-50行数据单位ms)测试结果是在相同操作系统下进行的并且都有预热ExecuteMySqlBulkCopy 方法在 FreeSql.Provider.MySqlConnector 中实现的12|0Sqlite :memory: 内存模式了解 EFCore 应该知道有一个 inMemory 实现Sqlite 其实也有内存模式所以在非常棒忍不住的 FreeSql.Provider.Sqlite 稍加适配就可以实现 inMemory 模式了。使用 inMemory 模式非常简单只需要修改 IFreeSql 创建的类型以及连接字符串即可static IFreeSql fsql new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.Sqlite, Data Source:memory:).UseAutoSyncStructure(true) //自动同步实体结构到数据库.Build(); //请务必定义成 Singleton 单例模式
内存模式 FreeSql CodeFirst 功能用起来体验还是不错的。因为每次都要迁移结构fsql 释放数据就没了。13|0终于写完了终于写完了这篇文章是我有史以来编辑最长时间的历时 4小时原本我可以利用这 4小时编写一堆胶水代码却非要写推广的文章真心希望正在使用的、善良的您能动一动小手指把文章转发一下让更多人知道 .NET 有这样一个好用的 ORM 存在。谢谢了FreeSql 开源协议 MIT https://github.com/dotnetcore/FreeSql可以商用文档齐全。QQ开发群4336577CSRedisCore 说FreeSql 的待遇也好太多了。如果你有好的 ORM 实现想法欢迎给作者留言讨论谢谢观看