using FreeSql.DataAnnotations; using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Threading; // ReSharper disable CheckNamespace // ReSharper disable InconsistentNaming // ReSharper disable InconsistentlySynchronizedField namespace FreeSql { /// /// Entity base class, including CreateTime/UpdateTime/IsDeleted. /// /// 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 /// [Table(DisableSyncStructure = true)] public abstract class BaseEntity { static Func _resoleOrm; internal static Func _resolveUow; public static IFreeSql Orm => _resoleOrm?.Invoke() ?? throw new Exception(CoreStrings.S_BaseEntity_Initialization_Error); public static void Initialization(IFreeSql fsql, Func resolveUow) => Initialization(() => fsql, resolveUow); public static void Initialization(Func resoleOrm, Func resolveUow) { _resoleOrm = resoleOrm; _resolveUow = resolveUow; if (_configEntityQueues.Any()) { lock (_configEntityLock) { while (_configEntityQueues.TryDequeue(out var cei)) Orm.CodeFirst.ConfigEntity(cei.EntityType, cei.Fluent); } } } class ConfigEntityInfo { public Type EntityType; public Action Fluent; } static readonly ConcurrentQueue _configEntityQueues = new ConcurrentQueue(); static readonly object _configEntityLock = new object(); internal static void ConfigEntity(Type entityType, Action fluent) { lock (_configEntityLock) { if (_resoleOrm?.Invoke() == null) _configEntityQueues.Enqueue(new ConfigEntityInfo { EntityType = entityType, Fluent = fluent }); else Orm.CodeFirst.ConfigEntity(entityType, fluent); } } /// /// Created time
/// 创建时间 ///
[Column(Position = -4)] public virtual DateTime CreateTime { get; set; } = DateTime.Now; /// /// Updated time
/// 更新时间 ///
[Column(Position = -3)] public virtual DateTime UpdateTime { get; set; } /// /// Logical Delete
/// 逻辑删除 ///
[Column(Position = -2)] public virtual bool IsDeleted { get; set; } /// /// Sort
/// 排序 ///
[Column(Position = -1)] public virtual int Sort { get; set; } } /// /// A readonly entity base class, including CreateTime/UpdateTime/IsDeleted. /// /// 包括 CreateTime/UpdateTime/IsDeleted 的只读实体基类 /// /// [Table(DisableSyncStructure = true)] public abstract class BaseEntityReadOnly : BaseEntity where TEntity : class { /// /// To query data
/// 查询数据 ///
/// 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 baseRepo = 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 (itemType.GetConstructor(Type.EmptyTypes) == null) return; if (item is BaseEntity == false) return; } if (item is BaseEntity entity) { if (baseRepo == null) baseRepo = Orm.GetRepository(); entity.Repository = baseRepo; entity.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) { if (item is BaseEntity entity) { if (repo == null) repo = Orm.GetRepository(); entity.Repository = repo; entity.Attach(); } } } /// /// Query conditions
/// 查询条件,Where(a => a.Id> 10) /// /// Support navigation object query
/// 支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") ///
/// lambda表达式 /// public static ISelect Where(Expression> exp) => Select.Where(exp); /// /// Query conditions
/// 查询条件,Where(true, a => a.Id > 10) /// /// Support navigation object query
/// 支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") ///
/// true 时生效 /// lambda表达式 /// public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); /// /// Repository object.
/// 仓储对象 ///
protected IBaseRepository Repository { get; set; } /// /// To Attach entities. When updating data, only the changed part is updated.
/// 附加实体。在更新数据时,只更新变化的部分 ///
public TEntity Attach() { if (Repository == null) Repository = Orm.GetRepository(); var item = this as TEntity; Repository.Attach(item); return item; } } }