/// <summary> /// 使用一个 <see cref="MemberInitExpression"/> 表达式更新满足条件的一序列对象。 /// </summary> /// <param name="factory">一个构造实例并成员绑定的表达式。</param> /// <param name="predicate">用于测试每个元素是否满足条件的函数。</param> /// <returns>影响的实体数。</returns> public int Update(Expression <Func <TEntity> > factory, Expression <Func <TEntity, bool> > predicate) { var entity = EntityProxyManager.GetType(typeof(TEntity)).New <TEntity>(); entity.InitByExpression(factory); return(Update(entity, predicate)); }
/// <summary> /// 将 Json 转换为 <paramref name="dataType"/> 的代理对象。 /// </summary> /// <param name="serializer">当前的 <see cref="JsonSerializer"/> 对象。</param> /// <param name="reader"><see cref="JsonReader"/> 对象。</param> /// <param name="dataType">要反序列化的对象类型。</param> /// <returns></returns> public override object ReadJson(JsonSerializer serializer, JsonReader reader, Type dataType) { var proxyType = EntityProxyManager.GetType(dataType); var json = reader.ReadRaw(); return(serializer.Deserialize(json, proxyType)); }
private T MapInternal(Func <PropertyMapping, PropertyValue> func) { var proxyType = EntityProxyManager.GetType(typeof(T)); var entity = proxyType.New <IEntity>(); if (entity == null) { return(default(T)); } Initializer?.Invoke(entity); entity.SetState(EntityState.Unchanged); entity.As <ISupportInitializeNotification>(s => s.BeginInit()); foreach (var mapper in mapping) { var value = func(mapper); entity.InitializeValue(mapper.Property, value); } if (alwaysProperties != null) { foreach (var property in alwaysProperties) { EntityLazyloader.AsyncLoad(entity, property); } } entity.As <ISupportInitializeNotification>(s => s.EndInit()); return((T)entity); }
/// <summary> /// 使用一个 <see cref="MemberInitExpression"/> 表达式更新满足条件的一序列对象。 /// </summary> /// <param name="creator">一个构造实例并成员绑定的表达式。</param> /// <param name="predicate">用于测试每个元素是否满足条件的函数。</param> /// <returns>影响的实体数。</returns> public virtual int Update(Expression <Func <TEntity> > creator, Expression <Func <TEntity, bool> > predicate) { var entity = EntityProxyManager.GetType(ContextType, typeof(TEntity)).New <TEntity>(); entity.InitByExpression(creator); return(predicate == null?Update(entity) : Update(entity, predicate)); }
/// <summary> /// 异步的,使用一个 <see cref="MemberInitExpression"/> 表达式更新满足条件的一序列对象。 /// </summary> /// <param name="factory">一个构造实例并成员绑定的表达式。</param> /// <param name="predicate">用于测试每个元素是否满足条件的函数。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns>影响的实体数。</returns> public async Task <int> UpdateAsync(Expression <Func <TEntity> > factory, Expression <Func <TEntity, bool> > predicate, CancellationToken cancellationToken = default) { var entity = EntityProxyManager.GetType(typeof(TEntity)).New <TEntity>(); entity.InitByExpression(factory); return(predicate == null ? await UpdateAsync(entity, cancellationToken) : await UpdateAsync(entity, predicate, cancellationToken)); }
/// <summary> /// 使用一个 <see cref="MemberInitExpression"/> 表达式插入新的对象。 /// </summary> /// <param name="factory">一个构造实例并成员绑定的表达式。</param> /// <returns></returns> public int Insert(Expression <Func <TEntity> > factory) { var entity = EntityProxyManager.GetType(typeof(TEntity)).New <TEntity>(); entity.InitByExpression(factory); return(Insert(entity)); }
/// <summary> /// 使用一个 <see cref="MemberInitExpression"/> 表达式插入新的对象。 /// </summary> /// <param name="creator">一个构造实例并成员绑定的表达式。</param> /// <returns>如果主键是自增类型,则为主键值,否则为影响的实体数。</returns> public virtual int Insert(Expression <Func <TEntity> > creator) { var entity = EntityProxyManager.GetType(ContextType, typeof(TEntity)).New <TEntity>(); entity.InitByExpression(creator); return(Insert(entity)); }
private T MapInternal(Func <PropertyMapping, PropertyValue> func) { var proxyType = EntityProxyManager.GetType((Type)null, typeof(T)); var entity = proxyType.New <IEntity>(); if (entity == null) { return(default);
/// <summary> /// 异步的,使用一个 <see cref="MemberInitExpression"/> 表达式插入新的对象。 /// </summary> /// <param name="factory">一个构造实例并成员绑定的表达式。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns>如果主键是自增类型,则为主键值,否则为影响的实体数。</returns> public async Task <int> InsertAsync(Expression <Func <TEntity> > factory, CancellationToken cancellationToken = default) { var entity = EntityProxyManager.GetType(typeof(TEntity)).New <TEntity>(); entity.InitByExpression(factory); return(await InsertAsync(entity, cancellationToken)); }
/// <summary> /// 使用初始化函数将一个新的实体对象插入到库。 /// </summary> /// <param name="initializer">一个初始化实体成员绑定的函数。</param> /// <returns>如果主键是自增类型,则为主键值,否则为影响的实体数。</returns> public virtual int Insert(Action <TEntity> initializer) { Guard.ArgumentNull(initializer, nameof(initializer)); var entity = EntityProxyManager.GetType(ContextType, typeof(TEntity)).New <TEntity>(); initializer(entity); return(Insert(entity)); }
/// <summary> /// 异步的,使用一个 <see cref="MemberInitExpression"/> 表达式插入新的对象。 /// </summary> /// <param name="creator">一个构造实例并成员绑定的表达式。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns>如果主键是自增类型,则为主键值,否则为影响的实体数。</returns> public async virtual Task <int> InsertAsync(Expression <Func <TEntity> > creator, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var entity = EntityProxyManager.GetType(ContextType, typeof(TEntity)).New <TEntity>(); entity.InitByExpression(creator); return(await InsertAsync(entity, cancellationToken)); }
/// <summary> /// 异步的,使用一个 <see cref="MemberInitExpression"/> 表达式更新满足条件的一序列对象。 /// </summary> /// <param name="creator">一个构造实例并成员绑定的表达式。</param> /// <param name="predicate">用于测试每个元素是否满足条件的函数。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns>影响的实体数。</returns> public async virtual Task <int> UpdateAsync(Expression <Func <TEntity> > creator, Expression <Func <TEntity, bool> > predicate, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var entity = EntityProxyManager.GetType(ContextType, typeof(TEntity)).New <TEntity>(); entity.InitByExpression(creator); return(predicate == null ? await UpdateAsync(entity, cancellationToken) : await UpdateAsync(entity, predicate, cancellationToken)); }
/// <summary> /// 使用初始化函数更新满足条件的一序列对象。 /// </summary> /// <param name="initializer">一个初始化实体成员绑定的函数。</param> /// <param name="predicate">用于测试每个元素是否满足条件的函数。</param> /// <returns>影响的实体数。</returns> public virtual int Update(Action <TEntity> initializer, Expression <Func <TEntity, bool> > predicate) { Guard.ArgumentNull(initializer, nameof(initializer)); var entity = EntityProxyManager.GetType(ContextType, typeof(TEntity)).New <TEntity>(); initializer(entity); return(predicate == null?Update(entity) : Update(entity, predicate)); }
/// <summary> /// 异步的,使用初始化函数将一个新的实体对象插入到库。 /// </summary> /// <param name="initializer">一个初始化实体成员绑定的函数。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns>如果主键是自增类型,则为主键值,否则为影响的实体数。</returns> public async virtual Task <int> InsertAsync(Action <TEntity> initializer, CancellationToken cancellationToken = default) { Guard.ArgumentNull(initializer, nameof(initializer)); cancellationToken.ThrowIfCancellationRequested(); var entity = EntityProxyManager.GetType(ContextType, typeof(TEntity)).New <TEntity>(); initializer(entity); return(await InsertAsync(entity, cancellationToken)); }
/// <summary> /// 异步的,使用初始化函数更新满足条件的一序列对象。 /// </summary> /// <param name="initializer">一个初始化实体成员绑定的函数。</param> /// <param name="predicate">用于测试每个元素是否满足条件的函数。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns>影响的实体数。</returns> public async virtual Task <int> UpdateAsync(Action <TEntity> initializer, Expression <Func <TEntity, bool> > predicate, CancellationToken cancellationToken = default) { Guard.ArgumentNull(initializer, nameof(initializer)); cancellationToken.ThrowIfCancellationRequested(); var entity = EntityProxyManager.GetType(ContextType, typeof(TEntity)).New <TEntity>(); initializer(entity); return(predicate == null ? await UpdateAsync(entity, cancellationToken) : await UpdateAsync(entity, predicate, cancellationToken)); }
/// <summary> /// 构造一个代理对象。 /// </summary> /// <param name="applyDefaultValue">是否应用默认值。</param> /// <returns></returns> public static TEntity New(bool applyDefaultValue) { var proxyType = EntityProxyManager.GetType(typeof(TEntity)); var entity = proxyType.New <TEntity>(); if (applyDefaultValue) { return((TEntity)entity.ApplyDefaultValue()); } return(entity); }
/// <summary> /// 构造一个实体代理对象。 /// </summary> /// <param name="context"></param> /// <param name="entityType">实体类型。</param> /// <param name="applyDefaultValue">是否应用默认值。</param> /// <returns></returns> public static IEntity New <TContext>(this TContext context, Type entityType, bool applyDefaultValue) where TContext : EntityContext { var provider = (IProvider)context.GetService(typeof(IProvider)); var proxyType = EntityProxyManager.GetType(typeof(TContext), entityType); var entity = proxyType.New <IEntity>(); if (applyDefaultValue) { return(entity.ApplyDefaultValue()); } return(entity); }
/// <summary> /// 构造一个代理对象。 /// </summary> /// <returns></returns> public static TEntity New() { var proxyType = EntityProxyManager.GetType(typeof(TEntity)); return(proxyType.New <TEntity>()); }
/// <summary> /// 将 Json 转换为 <paramref name="dataType"/> 的代理对象。 /// </summary> /// <param name="serializer"></param> /// <param name="dataType"></param> /// <param name="json"></param> /// <returns></returns> public override object ReadJson(JsonSerializer serializer, Type dataType, string json) { var proxyType = EntityProxyManager.GetType(dataType); return(serializer.Deserialize(json, proxyType)); }
// <summary> // Processes the given context type to determine the EntityRepository or IRepository // properties and collect root entity types from those properties. Also, delegates are // created to initialize any of these properties that have public setters. // If the type has been processed previously in the app domain, then all this information // is returned from a cache. // </summary> // <returns> A dictionary of potential entity type to the list of the names of the properties that used the type. </returns> private Dictionary <Type, List <string> > GetSets() { EntityContextTypesInitializersPair setsInfo; var contextType = _context.GetType(); if (!_objectSetInitializers.TryGetValue(contextType, out setsInfo)) { // It is possible that multiple threads will enter this code and create the list // and the delegates. However, the result will always be the same so we may, in // the rare cases in which this happens, do some work twice, but functionally the // outcome will be correct. var dbContextParam = Expression.Parameter(typeof(EntityContext), "dbContext"); var initDelegates = new List <Action <EntityContext> >(); var typeMap = new Dictionary <Type, List <string> >(); var injection = _service.Provider.GetService <IInjectionProvider>(); // Properties declared directly on DbContext such as Database are skipped foreach (var propertyInfo in contextType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.GetIndexParameters().Length == 0 && p.DeclaringType != typeof(EntityContext))) { var entityType = GetSetType(propertyInfo.PropertyType); if (entityType != null) { EntityProxyManager.CompileAll(entityType.Assembly, injection); // We validate immediately because a DbSet/IDbSet must be of // a valid entity type since otherwise you could never use an instance. if (!entityType.IsValidStructuralType()) { //throw Error.InvalidEntityType(entityType); } if (!typeMap.TryGetValue(entityType, out List <string> properties)) { properties = new List <string>(); typeMap[entityType] = properties; } properties.Add(propertyInfo.Name); var setter = propertyInfo.GetSetMethod(); if (setter != null && setter.IsPublic) { var setMethod = MthSetRep.MakeGenericMethod(entityType); Expression expression = Expression.Call(dbContextParam, setMethod); var pType = setter.GetParameters()[0].ParameterType; if (pType != expression.Type) { expression = Expression.Convert(expression, pType); } var setExp = Expression.Call( Expression.Convert(dbContextParam, contextType), setter, expression); #if !NET35 var createExp = Expression.Call(Expression.Constant(_service), MthTryCreateRep, Expression.Constant(entityType)); var blockExp = Expression.Block(setExp, createExp); initDelegates.Add( Expression.Lambda <Action <EntityContext> >(blockExp, dbContextParam).Compile()); #else initDelegates.Add( Expression.Lambda <Action <EntityContext> >(setExp, dbContextParam).Compile()); #endif } } } Action <EntityContext> initializer = dbContext => { foreach (var initer in initDelegates) { initer(dbContext); } }; setsInfo = new EntityContextTypesInitializersPair(typeMap, initializer); // If TryAdd fails it just means some other thread got here first, which is okay // since the end result is the same info anyway. _objectSetInitializers.TryAdd(_context.GetType(), setsInfo); } return(setsInfo.EntityTypeToPropertyNameMap); }