예제 #1
0
        /// <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));
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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));
        }
예제 #5
0
        /// <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));
        }
예제 #6
0
        /// <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));
        }
예제 #7
0
        /// <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));
        }
예제 #8
0
        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);
예제 #9
0
        /// <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));
        }
예제 #10
0
        /// <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));
        }
예제 #11
0
        /// <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));
        }
예제 #12
0
        /// <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));
        }
예제 #13
0
        /// <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));
        }
예제 #14
0
        /// <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));
        }
예제 #15
0
        /// <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));
        }
예제 #16
0
        /// <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);
        }
예제 #18
0
        /// <summary>
        /// 构造一个代理对象。
        /// </summary>
        /// <returns></returns>
        public static TEntity New()
        {
            var proxyType = EntityProxyManager.GetType(typeof(TEntity));

            return(proxyType.New <TEntity>());
        }
예제 #19
0
        /// <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));
        }
예제 #20
0
        // <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);
        }