FreeSql/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs
28810 f434418b2c ## v0.9.17 (ODBC)
- 增加 FreeSql.Provider.Odbc,实现 Oracle/SqlServer/MySql 的 Odbc 访问提供;
- 增加 FreeSqlBuilder.UseConnectionString 参数 providerType,可解决因包版本冲突时,可能无法反射获得 FreeSql.Provider 对应的类型,通常这个参数不需要设置;
- 优化 MaxLength 特性,当指定为 -1 时 DbType 会分别映射类型 text/nvarchar(max)/nvarchar2(4000);
2019-09-19 23:14:30 +08:00

88 lines
3.7 KiB
C#

using FreeSql.DataAnnotations;
using FreeSql.Extensions.EntityUtil;
using FreeSql.Internal.Model;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace FreeSql.Internal.CommonProvider
{
public abstract partial class CodeFirstProvider : ICodeFirst
{
protected IFreeSql _orm;
protected CommonUtils _commonUtils;
protected CommonExpression _commonExpression;
public CodeFirstProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
{
_orm = orm;
_commonUtils = commonUtils;
_commonExpression = commonExpression;
}
public bool IsAutoSyncStructure { get; set; } = false;
public bool IsSyncStructureToLower { get; set; } = false;
public bool IsSyncStructureToUpper { get; set; } = false;
public bool IsConfigEntityFromDbFirst { get; set; } = false;
public virtual bool IsNoneCommandParameter { get; set; } = false;
public bool IsLazyLoading { get; set; } = false;
public abstract (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type);
public ICodeFirst ConfigEntity<T>(Action<TableFluent<T>> entity) => _commonUtils.ConfigEntity(entity);
public ICodeFirst ConfigEntity(Type type, Action<TableFluent> entity) => _commonUtils.ConfigEntity(type, entity);
public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type);
public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type);
public string GetComparisonDDLStatements<TEntity>() => this.GetComparisonDDLStatements(typeof(TEntity));
public abstract string GetComparisonDDLStatements(params Type[] entityTypes);
static object syncStructureLock = new object();
internal ConcurrentDictionary<Type, bool> dicSyced = new ConcurrentDictionary<Type, bool>();
public bool SyncStructure<TEntity>() => this.SyncStructure(typeof(TEntity));
public bool SyncStructure(params Type[] entityTypes)
{
if (entityTypes == null) return false;
var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray().Distinct().ToArray();
if (syncTypes.Any() == false) return false;
var before = new Aop.SyncStructureBeforeEventArgs(entityTypes);
_orm.Aop.SyncStructureBefore?.Invoke(this, before);
Exception exception = null;
string ddl = null;
try
{
lock (syncStructureLock)
{
ddl = this.GetComparisonDDLStatements(syncTypes);
if (string.IsNullOrEmpty(ddl))
{
foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true);
return true;
}
var affrows = ExecuteDDLStatements(ddl);
foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true);
return true;
}
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception);
_orm.Aop.SyncStructureAfter?.Invoke(this, after);
}
}
public virtual int ExecuteDDLStatements(string ddl) => _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl);
}
}