- 常见问题
- 1、如何监视 SQL?
- 2、MySql Enum 映射
- 3、多个 IFreeSql 实例,如何注入使用?
- 4、TransactionalAttribute + UnitOfWorkManager 事务传播
- 5、怎么执行 SQL 返回实体列表?
- 6、错误:【主库】状态不可用,等待后台检查程序恢复方可使用。xxx
- 7、错误:【主库】对象池已释放,无法访问。
- 8、错误:ObjectPool.Get 获取超时(10秒)。
- 9、多平台代码参考,使用自定义SqliteProvider,例如Sqlite用Microsoft.Data.Sqlite或者反射Mono.Data.Sqlite.
- 10、 2.6.100升级到3.0.100 后无法连接 sqlserver 提示证书无效, 提示证书链是由不受信任的颁发机构颁发的.
常见问题
1、如何监视 SQL?
方法一:UseMonitorCommand + UseNoneCommandParameter
static IFreeSql fsql = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, "...").UseMonitorCommand(cmd => Console.WriteLine($"线程:{cmd.CommandText}\r\n")).UseNoneCommandParameter(true).Build();
方法二:Aop.CurdBefore/CurdAfter
fsql.Aop.CurdAfter += (s, e) =>{if (e.ElapsedMilliseconds > 200)Console.WriteLine($"线程:{e.Sql}\r\n");};
2、MySql Enum 映射
默认情况 c# 枚举会映射为 MySql Enum 类型,如果想映射为 int 在 FreeSqlBuilder Build 之后执行以下 Aop 统一处理:
fsql.Aop.ConfigEntityProperty += (s, e) => {if (e.Property.PropertyType.IsEnum)e.ModifyResult.MapType = typeof(int);};
3、多个 IFreeSql 实例,如何注入使用?
https://github.com/dotnetcore/FreeSql/issues/44
4、TransactionalAttribute + UnitOfWorkManager 事务传播
https://github.com/dotnetcore/FreeSql/issues/289
5、怎么执行 SQL 返回实体列表?
//直接查询fsql.Ado.Query<T>(sql);//嵌套一层做二次查询fsql.Select<T>().WithSql(sql).Page(1, 10).ToList();
6、错误:【主库】状态不可用,等待后台检查程序恢复方可使用。xxx
一般是数据库连接失败,才会出现,请检查程序与数据库之间的网络。具体按 xxx 给出的提示进行排查。
7、错误:【主库】对象池已释放,无法访问。
原因一:手工调用了 fsql.Dispose,之后仍然使用它
原因二:使用了 IdleBus 管理 IFreeSql,错误的方式如下:
- a) 不要构建了 IFreeSql 再丢去注册
var fsql = new FreeSqlBulder()...Build();ib.Register("key01", () => fsql); //错了,错了,错了ib.Register("key01", () => new FreeSqlBulder()...Build()); //正确
- b) 尽量每次都使用 ib.Get 获得 IFreeSql 对象(避免存对象引用),IdleBus 内部超时释机制一时触发,再使用引用对象,就会报这个报错
原因三:检查项目的系统事件,是否在异常之前触发
AppDomain.CurrentDomain.ProcessExit += (s1, e1) =>{//记录日志};Console.CancelKeyPress += (s1, e1) =>{//记录日志};
如果确定问题,可以在 FreeSqlBuilder 构建对象的时候 UseExitAutoDisposePool(false) 关闭这个机制
8、错误:ObjectPool.Get 获取超时(10秒)。
原因一:UnitOfWork 使用未释放,请保证程序内使用 UnitOfWork 的地方会执行 Dispose
原因二:Max Pool Size 设置过小,程序访问量过高
监视 fsql.Ado.MasterPool.Statistics,它的值:Pool: 5/100, Get wait: 0, GetAsync await: 0
5 为可用连接数,值为0后开始排队100 为当前最大连接数Get await 为同步方法获取连接的排队数量(超过10秒就会报错)GetAsync await 为异步方法获取连接的排队数量
监视 FreeSql.UnitOfWork.DebugBeingUsed 这个静态字典,存储正在使用事务的工作单元
注意:尽量不要使用 fsql.Ado.MasterPool.Get() 或 GetAsync() 方法,否则请检查姿势。
9、多平台代码参考,使用自定义SqliteProvider,例如Sqlite用Microsoft.Data.Sqlite或者反射Mono.Data.Sqlite.
有条件的同学直接试试 FreeSql.Provider.SqliteCore 包,使用的就是Microsoft.Data.Sqlite驱动.
1.添加包
<PackageReference Include="FreeSql.Provider.Sqlite" Version="3.0.100" /><PackageReference Include = "Microsoft.Data.Sqlite" Version="6.0.3" />
2.代码
Microsoft.Data.Sqlite.SqliteConnection _database = new Microsoft.Data.Sqlite.SqliteConnection($"Data Source=document.db");var fsql = new FreeSql.FreeSqlBuilder().UseConnectionFactory(FreeSql.DataType.Sqlite, () => _database, typeof(FreeSql.Sqlite.SqliteProvider<>)).UseAutoSyncStructure(true).UseNoneCommandParameter(true) //必须开启,因为Microsoft.Data.Sqlite内插处理有bug.UseMonitorCommand(cmd => Console.Write(cmd.CommandText)).Build();
using System.Data.SQLite;string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqliteSample.db");SQLiteConnection _database = new SQLiteConnection($"Data Source={dbpath}");var fsql = new FreeSql.FreeSqlBuilder().UseConnectionFactory(FreeSql.DataType.Sqlite, () => _database, typeof(FreeSql.Sqlite.SqliteProvider<>)).Build();
Xamarin Forms,代码较多 主程序,接口获取rovider,各个平台自己实现.
if (Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.Android){fsql = new FreeSql.FreeSqlBuilder().UseConnectionFactory(FreeSql.DataType.Sqlite, () => DependencyService.Get<ISQLite>().GetConnectionSqlite("document"), typeof(FreeSql.Sqlite.SqliteProvider<>)).UseNoneCommandParameter(true).Build();}
10、 2.6.100升级到3.0.100 后无法连接 sqlserver 提示证书无效, 提示证书链是由不受信任的颁发机构颁发的.
请尝试:
1.连接字符串里加入 “Encrypt=True; TrustServerCertificate=True;”
2.使用FreeSql.Provider.SqlServerForSystem替换FreeSql.Provider.SqlServer
深入讨论请转到 https://github.com/dotnetcore/FreeSql/issues/992#issuecomment-1005305027
