using FreeSql; using System; using System.Collections.Generic; using System.Data; using System.Data.Common; public static class FreeSqlAdoNetExtensions { static Dictionary _dicCurd = new Dictionary(); static object _dicCurdLock = new object(); static IFreeSql GetCrud(IDbConnection dbconn) { if (dbconn == null) throw new ArgumentNullException($"{nameof(dbconn)} 不能为 null"); ; Type dbconType = dbconn.GetType(); var connType = dbconType.UnderlyingSystemType; if (_dicCurd.TryGetValue(connType, out var fsql)) return fsql; Type providerType = null; switch (connType.Name) { case "MySqlConnection": providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(connType); if (providerType == null) providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(connType); if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); break; case "SqlConnection": providerType = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(connType); if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); break; case "NpgsqlConnection": providerType = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(connType); if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); break; case "OracleConnection": providerType = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(connType); if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); break; case "SQLiteConnection": providerType = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(connType); if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); break; case "DmConnection": providerType = Type.GetType("FreeSql.Dameng.DamengProvider`1,FreeSql.Provider.Dameng")?.MakeGenericType(connType); if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Dameng.dll,可前往 nuget 下载"); break; case "OscarConnection": providerType = Type.GetType("FreeSql.ShenTong.ShenTongProvider`1,FreeSql.Provider.ShenTong")?.MakeGenericType(connType); if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.ShenTong.dll,可前往 nuget 下载"); break; default: throw new Exception("未实现"); } lock (_dicCurdLock) { if (_dicCurd.TryGetValue(connType, out fsql)) return fsql; lock (_dicCurdLock) _dicCurd.Add(connType, fsql = Activator.CreateInstance(providerType, new object[] { null, null, null }) as IFreeSql); } return fsql; } static IFreeSql GetCrud(IDbTransaction dbtran) { if (dbtran == null) throw new ArgumentNullException($"{nameof(dbtran)} 不能为 null"); return GetCrud(dbtran.Connection); } /// /// 获取 IDbConnection 对应的 IFreeSql 实例 /// /// /// public static IFreeSql GetIFreeSql(this IDbConnection that) => GetCrud(that); #region IDbConnection /// /// 插入数据 /// /// /// public static IInsert Insert(this IDbConnection that) where T1 : class => GetCrud(that).Insert().WithConnection(that as DbConnection); /// /// 插入数据,传入实体 /// /// /// /// public static IInsert Insert(this IDbConnection that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); /// /// 插入数据,传入实体数组 /// /// /// /// public static IInsert Insert(this IDbConnection that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); /// /// 插入数据,传入实体集合 /// /// /// /// public static IInsert Insert(this IDbConnection that, List source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); /// /// 插入数据,传入实体集合 /// /// /// /// public static IInsert Insert(this IDbConnection that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); /// /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: /// MySql 5.6+: on duplicate key update /// PostgreSQL 9.4+: on conflict do update /// SqlServer 2008+: merge into /// Oracle 11+: merge into /// Sqlite: replace into /// 达梦: merge into /// 人大金仓:on conflict do update /// 神通:merge into /// MsAccess:不支持 /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) /// /// /// public static IInsertOrUpdate InsertOrUpdate(this IDbConnection that) where T1 : class => GetCrud(that).InsertOrUpdate().WithConnection(that as DbConnection); /// /// 修改数据 /// /// /// public static IUpdate Update(this IDbConnection that) where T1 : class => GetCrud(that).Update().WithConnection(that as DbConnection); /// /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IUpdate Update(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithConnection(that as DbConnection); /// /// 查询数据 /// /// /// public static ISelect Select(this IDbConnection that) where T1 : class => GetCrud(that).Select().WithConnection(that as DbConnection); /// /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static ISelect Select(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithConnection(that as DbConnection); /// /// 删除数据 /// /// /// public static IDelete Delete(this IDbConnection that) where T1 : class => GetCrud(that).Delete().WithConnection(that as DbConnection); /// /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IDelete Delete(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithConnection(that as DbConnection); #endregion #region IDbTransaction /// /// 插入数据 /// /// /// public static IInsert Insert(this IDbTransaction that) where T1 : class => GetCrud(that).Insert().WithTransaction(that as DbTransaction); /// /// 插入数据,传入实体 /// /// /// /// public static IInsert Insert(this IDbTransaction that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); /// /// 插入数据,传入实体数组 /// /// /// /// public static IInsert Insert(this IDbTransaction that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); /// /// 插入数据,传入实体集合 /// /// /// /// public static IInsert Insert(this IDbTransaction that, List source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); /// /// 插入数据,传入实体集合 /// /// /// /// public static IInsert Insert(this IDbTransaction that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); /// /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: /// MySql 5.6+: on duplicate key update /// PostgreSQL 9.4+: on conflict do update /// SqlServer 2008+: merge into /// Oracle 11+: merge into /// Sqlite: replace into /// 达梦: merge into /// 人大金仓:on conflict do update /// 神通:merge into /// MsAccess:不支持 /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) /// /// /// public static IInsertOrUpdate InsertOrUpdate(this IDbTransaction that) where T1 : class => GetCrud(that).InsertOrUpdate().WithTransaction(that as DbTransaction); /// /// 修改数据 /// /// /// public static IUpdate Update(this IDbTransaction that) where T1 : class => GetCrud(that).Update().WithTransaction(that as DbTransaction); /// /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IUpdate Update(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithTransaction(that as DbTransaction); /// /// 查询数据 /// /// /// public static ISelect Select(this IDbTransaction that) where T1 : class => GetCrud(that).Select().WithTransaction(that as DbTransaction); /// /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static ISelect Select(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithTransaction(that as DbTransaction); /// /// 删除数据 /// /// /// public static IDelete Delete(this IDbTransaction that) where T1 : class => GetCrud(that).Delete().WithTransaction(that as DbTransaction); /// /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IDelete Delete(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithTransaction(that as DbTransaction); #endregion }