FreeSql 项目从2018年11月28日开发至今,版本已发布至 v0.3.12,版本规则:年数-月-日-当日版本号。目前主要包括 FreeSql、FreeSql.Repository 两个项目的维护和开发。这篇文章介绍有哪些贴心功能。

错误:传入的请求具有过多的参数。该服务器支持最多 2100 个参数。请减少参数的数目,然后重新发送该请求。

不知道其他 orm 批量添加实体到 sqlserver 有没有这个错误,FreeSql 不存在。

实体类配置

每款 orm 都会有自己一套实体类配置方法,当项目的实体被多个 orm 同时使用时将成为问题,因为不可能做多套配置,FreeSql 提供了以下几种的方法,免入侵式配置;

1、如果你从数据库生成的实体,FreeSql 提供 IsConfigEntityFromDbFirst 参数,可从数据库导入主键、自键等配置信息;

var orm = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
.UseAutoSyncStructure(true) //只需要在这里控制,默认为关闭状态
.UseConfigEntityFromDbFirst(true) .Build();

2、如果你已经使用 EF 建好了实体模式,FreeSql 提供了从 EF 元数据导入;

public static void ConfigEntity(this ICodeFirst codeFirst, IModel efmodel) {
foreach (var type in efmodel.GetEntityTypes()) {
codeFirst.ConfigEntity(type.ClrType, a => {
//表名
var relationalTableName = type.FindAnnotation("Relational:TableName");
if (relationalTableName != null) {
a.Name(relationalTableName.Value?.ToString() ?? type.ClrType.Name);
} foreach (var prop in type.GetProperties()) {
var freeProp = a.Property(prop.Name);
//列名
var relationalColumnName = prop.FindAnnotation("Relational:ColumnName");
if (relationalColumnName != null) {
freeProp.Name(relationalColumnName.Value?.ToString() ?? prop.Name);
}
//主键
freeProp.IsPrimary(prop.IsPrimaryKey());
//自增
freeProp.IsIdentity(
prop.ValueGenerated == ValueGenerated.Never ||
prop.ValueGenerated == ValueGenerated.OnAdd ||
prop.GetAnnotations().Where(z =>
z.Name == "SqlServer:ValueGenerationStrategy" && z.Value.ToString().Contains("IdentityColumn") //sqlserver 自增
|| z.Value.ToString().Contains("IdentityColumn") //其他数据库实现未经测试
).Any()
);
//可空
freeProp.IsNullable(prop.AfterSaveBehavior != PropertySaveBehavior.Throw);
//类型
var relationalColumnType = prop.FindAnnotation("Relational:ColumnType");
if (relationalColumnType != null) {
var dbType = relationalColumnType.ToString();
if (!string.IsNullOrEmpty(dbType)) {
var maxLength = prop.FindAnnotation("MaxLength");
if (maxLength != null)
dbType += $"({maxLength})";
freeProp.DbType(dbType);
}
}
}
});
}
}

3、如果你使用了其他 orm,FreeSql 提供 ConfigEntity,使用类似 2 的做法来完成配置导入;

事务

FreeSql 提供了同线程事务、对外开放事务。

同线程事务

假设用户购买了价值100元的商品:

第一步:扣余额;

第二步:扣库存;

第一步成功了,到了第二步发现库存不足时,事务可以回滚,扣余额的数据将不生效。

//假设已经有了其他wiki页的IFreeSql声明
orm.Transaction(() => { var affrows = orm.Update<User>().Set(a => a.Wealth - 100)
.Where(a => a.Wealth >= 100)
//判断别让用户余额扣成负数
.ExecuteAffrows();
if (affrows < 1) {
throw new Exception("用户余额不足");
//抛出异常,事务退出
} affrows = orm.Update<Goods>().Set(a => a.Stock - 1)
.Where(a => a.Stock > 0)
//判断别让用库存扣成负数
.ExecuteAffrows();
if (affrows < 1) {
throw new Exception("商品库存不足");
//抛出异常,回滚事务,事务退出
//用户余额的扣除将不生效
} //程序执行在此处,说明都扣成功了,事务完成并提交
});

注意与说明:

1、数据库事务在线程挂载,每个线程只可开启一个事务连接,重复开启会获取线程已开启的事务;

2、在事务代码过程中,不可使用异步方法,包括FreeSql提供的数据库异步方法,否则线程将会切换事务不生效;

3、orm.Transaction 有防止死锁机制,60秒事务未结束的,将会被其他线程强行提交(不是回滚),可能造成不完整的事务,但仔细一想60秒还没完成的事务是什么原因呢?如果嫌60秒太少了可以在重载方法的参数中设置;

指定事务对象

除了上面提供的同线程事务外,FreeSql 还提供了指定事务对象的方法,将事务对象暴露给外部;

orm.Update<xxx>().WithTransaction(指定事务)
.Set(a => a.Clicks + 1).ExecuteAffrows();

ISelect、IInsert、IUpdate、IDelete,都支持 WithTransaction 方法。

仓储Repository

dotnet add package FreeSql.Repository

1、IFreeSql 的扩展方法;

var curd1 = orm.GetRepository<Song, int>();
var curd2 = orm.GetGuidRepository<Song>();

2、继承现实;

public class SongRepository : BaseRepository<Song, int> {
public SongRepository(IFreeSql orm) : base(orm) {} //在这里增加 CURD 以外的方法
}

3、Autofac 注入;

public IServiceProvider ConfigureServices(IServiceCollection services) {
services.AddSingleton<IFreeSql>(orm);
services.AddMvc(); var builder = new ContainerBuilder(); //示范全局过滤的仓储类注入,如果实体中不存在 Title 属性,则条件不生效
builder.RegisterFreeRepositoryAddFilter<Song>(() => a => a.Title == DateTime.Now.ToString() + System.Threading.Thread.CurrentThread.ManagedThreadId); builder.Populate(services);
var container = builder.Build();
return new AutofacServiceProvider(container);
} //在控制器使用
public SongsController(GuidRepository<Song> repos1, GuidRepository<xxxx> repos2) {
}

Autofac 注入方式实现了全局【过滤与验证】的设定,方便租户功能的设计;

表达式函数

In查询

var t1 = orm.Select<xxx>().Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToSql();
//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime`
//FROM `tb_topic` a
//WHERE (a.`Id` in (1,2,3))

查找今天创建的数据

var t2 = orm.Select<xxx>().Where(a => a.CreateTime.Date == DateTime.Now.Date).ToSql();

不提供 SqlFunc 之类的伪函数,所支持的类型基本都可以使用对应的表达式函数,例如 日期、字符串、IN查询、数组(PostgreSQL的数组)、字典(PostgreSQL HStore)等等。

安全性

1、避免死锁的事务,超时自动提交;

2、未设置条件的删除、更新不生效;

3、仓储提供 filter 验证数据,确保数据的安全性;

......

更多特性可前往 wiki 中心查看

github: https://github.com/2881099/FreeSql

wiki: https://github.com/2881099/FreeSql/wiki/

非常贴心的轮子 FreeSql的更多相关文章

  1. 这年头做开源项目,被冷嘲热讽,FreeSql 0.0.4

    FreeSql 项目大概在20天前想着要做的,今天发布0.0.4在群里被一位大神讽刺. 这位无名氏哥们的观点,先声明这不是找安慰的文章,更加不是报复打击的目的. 1 所以这个比EF好在哪里 2 毕竟E ...

  2. 除非你是BAT,前端开发中最好少造轮子

    站在前人的肩膀上 HTML.CSS.JavaScript是前端的根基,这是无可否认的事实.正如一辆车当然都是由一堆钢板和螺钉组成的,但是现在还有人拎着个锤子敲敲打打的造车吗?李书福说过,“汽车不过是四 ...

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

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

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

    废话开头 这篇文章是我有史以来编辑最长时间的,历时 4小时!!!原本我可以利用这 4小时编写一堆胶水代码,真心希望善良的您点个赞,谢谢了!! 很久很久没有写文章了,上一次还是在元旦发布 1.0 版本的 ...

  5. [开源] .Net ORM FreeSql 1.8.0-preview 最新动态播报(番号:我还活着)

    写在开头 FreeSql 是 .NET 开源生态下的 ORM 轮子,在一些人眼里属于重复造轮子:不看也罢.就像昨天有位朋友截图某培训直播发给我看,内容为:"FreeSQL(个人产品),自己玩 ...

  6. 关于orm的个人测试——SqlSugar与FreeSql

    前言 转眼已经过了金九,光阴真的是似箭啊,周六日常加班,忙里抽闲就想鼓捣个啥看看,刚好最近想着有没有必要换个orm,从当时原生到Dapper,又到现在的Sqlsugar,因为经常听到几个不错的orm, ...

  7. [开源] .Net ORM FreeSql 1.10.0 稳步向行

    写在开头 FreeSql 是 .NET 开源生态下的 ORM 轮子,转眼快两年了,说真的开源不容易(只有经历过才明白).今天带点干货和湿货给大家,先说下湿货. 认识我的人,知道 CSRedisCore ...

  8. .Net orm 开源项目 FreeSql 2.0.0(满意的答卷)

    写在开头 2018年11月头脑发热到今天,一晃已经两年,当初从舒服区走向一个巨大的坑,回头一看后背一凉. 两年时间从无到有,经历数不清的日夜奋斗(有人问花了多长时间投入,答案:全职x2 + 两年无休息 ...

  9. .NET ORM 仓储层必备的功能介绍之 FreeSql Repository 实现篇

    写在开头 2018年11月的某一天,头脑发热开启了 FreeSql 开源项目之旅,时间一晃已经四年多,当初从舒服区走向一个巨大的坑,回头一看后背一凉.四年时间从无到有,经历了数不清的日夜奋战(有人问我 ...

随机推荐

  1. C语言 > 指向指针的指针

    Int **pt; 一个指向指针的指针: { int ** pt; //一个指向指针的指针; int *ppt; ; ppt = &a; pt = &ppt; printf(" ...

  2. Spring Boot实战笔记(二)-- Spring常用配置(Scope、Spring EL和资源调用)

    一.Bean的Scope Scope描述的是Spring容器如何新建Bean实例的.Spring的Scope有以下几种,通过@Scope注解来实现. (1)Singleton:一个Spring容器中只 ...

  3. 【转】JavaScript的异常处理

    当 JavaScript 引擎执行 JavaScript 代码时,有可能会发生各种异常,例如是语法异常,语言中缺少的功能,由于来自服务器或用户的异常输出而导致的异常. 而 Javascript 引擎是 ...

  4. 关于内核转储(core dump)的设置方法

    原作者:http://blog.csdn.net/wj_j2ee/article/details/7161586 1. 内核转储作用 (1) 内核转储的最大好处是能够保存问题发生时的状态. (2) 只 ...

  5. iPhone越狱

    手机越狱 常用工具:PP越狱助手.盘古越狱.iTunes 如果手机第一次越狱使用pp越狱助手成功率比较高 iPhone固件下载地址http://iphone.91.com/fw/iphone5/ 具体 ...

  6. ActiveMQ的使用

    ActiveMQ使用分为两大块:生产者和消费者 一.准备 项目导入jar包:activemq-all-5.15.3.jar 并buildpath    二.生产者 创建连接工厂 ActiveMQCon ...

  7. 第四章——训练模型(Training Models)

    前几章在不知道原理的情况下,已经学会使用了多个机器学习模型机器算法.Scikit-Learn很方便,以至于隐藏了太多的实现细节. 知其然知其所以然是必要的,这有利于快速选择合适的模型.正确的训练算法. ...

  8. HTTPS加密原理

    http(超文本传输协议) 一种属于应用层的协议 缺点: 通信使用明文(不加密),内容可能会被窃听 不验证通信方的身份,因此有可能遭遇伪装 无法证明报文的完整性,所以有可能已遭篡改 优点: 传输速度快 ...

  9. 用Hyperledger Fabric(超级账本)来构建Java语言开发区块链的环境

    面向 Java 开发人员的链代码简介 您或许听说过区块链,但可能不确定它对 Java™ 开发人员有何用.本教程将帮助大家解惑.我将分步展示如何使用 Hyperledger Fabric v0.6 来构 ...

  10. 关于Kafka监控方案的讨论

    之前在知乎上尝试过回答这个问题,后来问的人挺多,干脆在博客里面保存一下. 目前Kafka监控方案看似很多,然而并没有一个"大而全"的通用解决方案.各家框架也是各有千秋,以下是我了解 ...