using FreeSql.DataAnnotations; using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data.Common; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Threading; namespace FreeSql { /// /// 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 /// [Table(DisableSyncStructure = true)] public abstract class BaseEntity { internal static IFreeSql _ormPriv; /// /// 全局 IFreeSql orm 对象 /// public static IFreeSql Orm => _ormPriv ?? throw new Exception(@"使用前请初始化 BaseEntity.Initialization(new FreeSqlBuilder() .UseAutoSyncStructure(true) .UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") .Build());"); internal static Func _resolveUow; /// /// 初始化BaseEntity /// BaseEntity.Initialization(new FreeSqlBuilder() /// /// .UseAutoSyncStructure(true) /// /// .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") /// /// .Build()); /// /// IFreeSql orm 对象 /// 工作单元(事务)委托,如果不使用事务请传 null解释:由于AsyncLocal平台兼容不好,所以交给外部管理 public static void Initialization(IFreeSql fsql, Func resolveUow) { _ormPriv = fsql; _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine($"\r\n线程{Thread.CurrentThread.ManagedThreadId}: {e.Sql}\r\n"); if (_configEntityQueues.Any()) { lock (_configEntityLock) { while (_configEntityQueues.TryDequeue(out var cei)) _ormPriv.CodeFirst.ConfigEntity(cei.EntityType, cei.Fluent); } } _resolveUow = resolveUow; } class ConfigEntityInfo { public Type EntityType; public Action Fluent; } static ConcurrentQueue _configEntityQueues = new ConcurrentQueue(); static object _configEntityLock = new object(); internal static void ConfigEntity(Type entityType, Action fluent) { lock (_configEntityLock) { if (_ormPriv == null) _configEntityQueues.Enqueue(new ConfigEntityInfo { EntityType = entityType, Fluent = fluent }); else _ormPriv.CodeFirst.ConfigEntity(entityType, fluent); } } /// /// 创建时间 /// [Column(Position = -4)] public virtual DateTime CreateTime { get; set; } = DateTime.Now; /// /// 更新时间 /// [Column(Position = -3)] public virtual DateTime UpdateTime { get; set; } /// /// 逻辑删除 /// [Column(Position = -2)] public virtual bool IsDeleted { get; set; } /// /// 排序 /// [Column(Position = -1)] public virtual int Sort { get; set; } } [Table(DisableSyncStructure = true)] public abstract class BaseEntityReadOnly : BaseEntity where TEntity : class { /// /// 查询数据 /// /// public static ISelect Select { get { var select = Orm.Select() .TrackToList(TrackToList) //自动为每个元素 Attach .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction(false)); return select.WhereCascade(a => (a as BaseEntity).IsDeleted == false); } } static void TrackToList(object list) { if (list == null) return; var ls = list as IList; if (ls == null) { var ie = list as IEnumerable; if (ie == null) return; var isFirst = true; IBaseRepository berepo = null; foreach (var item in ie) { if (item == null) return; if (isFirst) { isFirst = false; var itemType = item.GetType(); if (itemType == typeof(object)) return; if (itemType.FullName.Contains("FreeSqlLazyEntity__")) itemType = itemType.BaseType; if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; if (item is BaseEntity == false) return; } var beitem = item as BaseEntity; if (beitem != null) { if (berepo == null) berepo = Orm.GetRepository(); beitem.Repository = berepo; beitem.Attach(); } } return; } if (ls.Any() == false) return; if (ls.FirstOrDefault() is BaseEntity == false) return; if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) return; IBaseRepository repo = null; foreach (var item in ls) { var beitem = item as BaseEntity; if (beitem != null) { if (repo == null) repo = Orm.GetRepository(); beitem.Repository = repo; beitem.Attach(); } } } /// /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") /// /// lambda表达式 /// public static ISelect Where(Expression> exp) => Select.Where(exp); /// /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") /// /// true 时生效 /// lambda表达式 /// public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); /// /// 仓储对象 /// protected IBaseRepository Repository { get; set; } /// /// 附加实体,在更新数据时,只更新变化的部分 /// public TEntity Attach() { if (this.Repository == null) this.Repository = Orm.GetRepository(); var item = this as TEntity; this.Repository.Attach(item); return item; } } }