コード例 #1
0
        /// <summary>
        /// 使用主键和外键对应构造一对多的关系。
        /// </summary>
        /// <param name="thisType"></param>
        /// <param name="otherType"></param>
        /// <returns></returns>
        private static RelationshipMetadata MakeOne2ManyMetadata(Type thisType, Type otherType)
        {
            var pks = PropertyUnity.GetPrimaryProperties(thisType).ToList();

            if (pks.Count > 0)
            {
                var fks  = pks.Select(s => PropertyUnity.GetProperty(otherType, s.Name)).ToList();
                var keys = new RelationshipKey[pks.Count];
                for (var i = 0; i < pks.Count; i++)
                {
                    if (fks[i] == null)
                    {
                        throw new Exception();
                    }

                    keys[i] = new RelationshipKey {
                        ThisKey = pks[i].Name, ThisProperty = pks[i], OtherKey = fks[i].Name, OtherProperty = fks[i]
                    };
                }

                return(new RelationshipMetadata(thisType, otherType, RelationshipStyle.One2Many, keys));
            }

            return(null);
        }
コード例 #2
0
        /// <summary>
        /// 检查有没有关联属性被修改.
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        private bool CheckRelationHasModified(IEntity entity)
        {
            //判断实体类型有是不是编译的代理类型,如果不是,取非null的属性,否则使用IsModified判断
            var isNotCompiled = entity.GetType().IsNotCompiled();

            return(PropertyUnity.GetRelatedProperties(entity.EntityType).Any(s => isNotCompiled ? !PropertyValue.IsEmpty(entity.GetValue(s)) : entity.IsModified(s.Name)));
        }
コード例 #3
0
ファイル: EntityExtension.cs プロジェクト: zhangbo27/fireasy
        /// <summary>
        /// 通过主键值使对象正常化。
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="keyValues">主键值数组。</param>
        /// <returns></returns>
        public static T Normalize <T>(this T entity, params object[] keyValues) where T : IEntity
        {
            var primaryKeys = PropertyUnity.GetPrimaryProperties(entity.EntityType).ToArray();

            if (primaryKeys.Length != 0 && keyValues == null ||
                primaryKeys.Length != keyValues.Length)
            {
                throw new Exception(SR.GetString(SRKind.DisaccordArgument, primaryKeys.Length, keyValues.Length));
            }

            var extend = entity as IEntityStatefulExtension;

            if (extend == null)
            {
                return(entity);
            }

            for (var i = 0; i < primaryKeys.Length; i++)
            {
                extend.InitializateValue(primaryKeys[i], PropertyValue.New(keyValues[i], primaryKeys[i].Type));
            }

            extend.SetState(EntityState.Modified);

            return(entity);
        }
コード例 #4
0
        /// <summary>
        /// 解析键对表达式。
        /// </summary>
        /// <param name="thisType"></param>
        /// <param name="otherType"></param>
        /// <param name="keyExpression">键对表达式,如 "父键1=>子键1,父键2=>子键2"。</param>
        private static IEnumerable <RelationshipKey> ParseRelationshipKeys(Type thisType, Type otherType, string keyExpression)
        {
            Guard.ArgumentNull(keyExpression, "keyExpression");

            var keys = keyExpression.Split(',');

            var list = new List <RelationshipKey>();

            foreach (var pair in keys.Where(pair => !string.IsNullOrEmpty(pair)))
            {
                string thisKey, otherKey;
                if (!ParseRelationKey(pair, out thisKey, out otherKey))
                {
                    continue;
                }
                list.Add(new RelationshipKey
                {
                    ThisKey       = thisKey,
                    ThisProperty  = PropertyUnity.GetProperty(thisType, thisKey),
                    OtherKey      = otherKey,
                    OtherProperty = PropertyUnity.GetProperty(otherType, otherKey)
                });
            }
            return(list);
        }
コード例 #5
0
        /// <summary>
        /// 获取可以组织到查询里的属性。
        /// </summary>
        /// <returns></returns>
        private IEnumerable <IProperty> GetUseableProperties()
        {
            foreach (var pkProperty in PropertyUnity.GetPrimaryProperties(entityType))
            {
                if (pkProperty != metaTree.InnerSign)
                {
                    yield return(pkProperty);
                }
            }

            yield return(metaTree.InnerSign);

            if (metaTree.Name != null)
            {
                yield return(metaTree.Name);
            }

            if (metaTree.FullName != null)
            {
                yield return(metaTree.FullName);
            }

            if (metaTree.Order != null)
            {
                yield return(metaTree.Order);
            }

            if (metaTree.Level != null)
            {
                yield return(metaTree.Level);
            }
        }
コード例 #6
0
        /// <summary>
        /// 将一个实体序列转换为 <see cref="DataTable"/> 对象。
        /// </summary>
        /// <typeparam name="TEntity">实体的类型。</typeparam>
        /// <param name="source">一个包含实体对象的序列。</param>
        /// <param name="tableName">指定 <see cref="DataTable"/> 的表名,如果忽略该参数,则根据实体的类型进行获取。</param>
        /// <param name="changedOnly">仅仅转换状态改变的实体。</param>
        /// <returns></returns>
        public static DataTable ToDataTable <TEntity>(this IEnumerable <TEntity> source, string tableName = null, bool changedOnly = false) where TEntity : IEntity
        {
            if (source.IsNullOrEmpty())
            {
                return(null);
            }
            var entityType = source.FirstOrDefault().GetType();
            var properties = new List <IProperty>(PropertyUnity.GetPersistentProperties(entityType));

            if (string.IsNullOrEmpty(tableName))
            {
                var metadata = EntityMetadataUnity.GetEntityMetadata(entityType);
                tableName = metadata.TableName;
            }

            var table = new DataTable(tableName);
            var keys  = CreateTableColumns(table, properties);

            var extendList = source.As <IEntitySetInternalExtension>();

            if (extendList != null && changedOnly)
            {
                FillDataTableRows(table, extendList, properties, keys.Length > 0);
            }
            else
            {
                FillDataTableRows(table, source, properties, keys.Length > 0);
            }
            if (keys.Length > 0)
            {
                var con = new UniqueConstraint(keys, true);
                table.Constraints.Add(con);
            }
            return(table);
        }
コード例 #7
0
 string[] IEntity.GetModifiedProperties()
 {
     return((from s in valueEntry.GetModifiedProperties()
             let p = PropertyUnity.GetProperty(entityType, s)
                     where p != null && (!p.Info.IsPrimaryKey || (p.Info.IsPrimaryKey && p.Info.GenerateType == IdentityGenerateType.None))
                     select s).ToArray());
 }
コード例 #8
0
        /// <summary>
        /// 检查实体的关联属性。
        /// </summary>
        /// <param name="entity"></param>
        private void HandleRelationProperties(IEntity entity)
        {
            //判断实体类型有是不是编译的代理类型,如果不是,取非null的属性,否则使用IsModified判断
            var isNotCompiled = entity.GetType().IsNotCompiled();
            var properties    = PropertyUnity.GetRelatedProperties(entity.EntityType).Where(m => isNotCompiled ?
                                                                                            !PropertyValue.IsEmpty(entity.GetValue(m)) :
                                                                                            entity.IsModified(m.Name));

            HandleRelationProperties(entity, properties);
        }
コード例 #9
0
        /// <summary>
        /// 检查实体的关联属性。
        /// </summary>
        /// <param name="entity"></param>
        private async Task HandleRelationPropertiesAsync(IEntity entity, CancellationToken cancellationToken = default)
        {
            //判断实体类型有是不是编译的代理类型,如果不是,取非null的属性,否则使用IsModified判断
            var isNotCompiled = entity.GetType().IsNotCompiled();
            var properties    = PropertyUnity.GetRelatedProperties(entity.EntityType).Where(m => isNotCompiled ?
                                                                                            !PropertyValue.IsEmpty(entity.GetValue(m)) :
                                                                                            entity.IsModified(m.Name));

            await HandleRelationPropertiesAsync(entity, properties, cancellationToken);
        }
コード例 #10
0
 internal static IEnumerable <PropertyFieldMapping> GetDbMapping(Type entityType)
 {
     return(from s in PropertyUnity.GetLoadedProperties(entityType, true)
            let name = string.IsNullOrEmpty(s.Info.FieldName) ? s.Name : s.Info.FieldName
                       let dbType = s.Info.DataType == null ? DbType.String : s.Info.DataType.Value
                                    select new PropertyFieldMapping(s.Name, s.Info.FieldName, s.Type, dbType)
     {
         ValueFunc = e => PropertyValueHelper.GetValueSafely(((IEntity)e).InternalGetValue(s))
     });
 }
コード例 #11
0
        /// <summary>
        /// 判断指定名称的属性的值是否已经创建。
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <returns></returns>
        internal bool IsValueCreated(string propertyName)
        {
            var property = PropertyUnity.GetProperty(entityType, propertyName);

            if (property is RelationProperty)
            {
                return(status.Contains(propertyName));
            }

            return(true);
        }
コード例 #12
0
        /// <summary>
        /// 获取指定属性的值。
        /// </summary>
        /// <param name="propertyName">实体属性。</param>
        /// <returns></returns>
        PropertyValue IEntity.GetValue(string propertyName)
        {
            var property = PropertyUnity.GetProperty(_entityType, propertyName);

            if (property == null)
            {
                throw new PropertyNotFoundException(propertyName);
            }

            return(GetValue(property));
        }
コード例 #13
0
 internal static IEnumerable <PropertyFieldMapping> GetDbMapping(Type entityType)
 {
     return(from s in PropertyUnity.GetLoadedProperties(entityType)
            where (!s.Info.IsPrimaryKey || (s.Info.IsPrimaryKey && s.Info.GenerateType != IdentityGenerateType.AutoIncrement))
            let name = string.IsNullOrEmpty(s.Info.FieldName) ? s.Name : s.Info.FieldName
                       let dbType = s.Info.DataType == null ? DbType.String : s.Info.DataType.Value
                                    select new PropertyFieldMapping(s.Name, s.Info.FieldName, s.Type, dbType)
     {
         ValueFunc = e => PropertyValue.GetValueSafely(((IEntity)e).GetValue(s))
     });
 }
コード例 #14
0
        private void InitMapping(string[] fields)
        {
            mapping                         = from s in PropertyUnity.GetProperties(typeof(T))
                                  let index = IndexOf(fields, s)
                                              where index != -1 && s is ILoadedProperty
                                              select new PropertyMapping {
                Property = s, Index = index
            };

            alwaysProperties = PropertyUnity.GetRelatedProperties(typeof(T), LoadBehavior.Always);
        }
コード例 #15
0
        /// <summary>
        /// 设置指定属性的值。
        /// </summary>
        /// <param name="propertyName">实体属性。</param>
        /// <param name="value">要设置的值。</param>
        void IEntity.SetValue(string propertyName, PropertyValue value)
        {
            var property = PropertyUnity.GetProperty(_entityType, propertyName);

            if (property == null)
            {
                throw new PropertyNotFoundException(propertyName);
            }

            SetValue(property, value);
        }
コード例 #16
0
ファイル: EntityExtension.cs プロジェクト: nodyang/fireasy2
        /// <summary>
        /// 为实体对象应用默认值。
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static IEntity ApplyDefaultValue(this IEntity entity)
        {
            foreach (var property in PropertyUnity.GetPersistentProperties(entity.EntityType))
            {
                if (!PropertyValue.IsEmpty(property.Info.DefaultValue))
                {
                    entity.InitializeValue(property, property.Info.DefaultValue);
                }
            }

            return(entity);
        }
コード例 #17
0
        /// <summary>
        /// 获取指定属性的值。
        /// </summary>
        /// <param name="instance">要读取的实体实例。</param>
        /// <param name="propertyName">要读取的属性的名称。</param>
        /// <returns>指定属性的值。</returns>
        public override object ReadValue(TEntity instance, string propertyName)
        {
            var property = PropertyUnity.GetProperty(typeof(TEntity), propertyName, true);

            if (property != null && property is ILoadedProperty)
            {
                var value = instance.InternalGetValue(property);
                return(PropertyValue.IsNullOrEmpty(value) ? null : value.GetStorageValue());
            }

            return(null);
        }
コード例 #18
0
ファイル: EntityExtension.cs プロジェクト: zhangbo27/fireasy
        /// <summary>
        /// 使用指定的实体的属性集来构造一个 <see cref="DataTable"/>,<see cref="DataTable"/> 里的列与实体属性一一对应。
        /// </summary>
        /// <param name="entityType">实体的类型。</param>
        /// <returns></returns>
        private static DataTable Construct(Type entityType)
        {
            Guard.ArgumentNull(entityType, "entityType");
            var metadata = EntityMetadataUnity.GetEntityMetadata(entityType);
            var table    = new DataTable(metadata.TableName);

            foreach (var property in PropertyUnity.GetPersistentProperties(entityType))
            {
                table.Columns.Add(property.ToDataColumn());
            }

            return(table);
        }
コード例 #19
0
        /// <summary>
        /// 设置默认值。
        /// </summary>
        /// <param name="entity"></param>
        protected virtual void SetDefaultValue(TEntity entity)
        {
            var isNotCompiled = entity.EntityType.IsNotCompiled();

            foreach (var property in PropertyUnity.GetPersistentProperties(EntityType))
            {
                var isModify = isNotCompiled ? !PropertyValue.IsEmpty(entity.GetValue(property)) : entity.IsModified(property.Name);
                if (!isModify && !PropertyValue.IsEmpty(property.Info.DefaultValue))
                {
                    entity.SetValue(property, property.Info.DefaultValue.TryAllotValue(property.Type, property.Info.DefaultValueFormatter));
                }
            }
        }
コード例 #20
0
        private bool InternalCreate(IEntity entity)
        {
            var parameters = new ParameterCollection();
            var context    = CreateContext(parameters);
            var sql        = EntityPersistentQueryBuilder.BuidCreateQuery(context, entity);

            if (!sql.IsNullOrEmpty())
            {
                var rootType = entity.EntityType.GetRootType();

                //找出自增长序列的属性
                var incProperty = PropertyUnity.GetPersistentProperties(rootType).FirstOrDefault(s => s.Info.GenerateType == IdentityGenerateType.AutoIncrement);

                if (incProperty != null)
                {
                    if (!string.IsNullOrEmpty(context.Syntax.IdentitySelect))
                    {
                        //获得当前插入的自增长序列值
                        var identitySelect = context.Syntax.IdentitySelect;
                        if (!identitySelect.StartsWith(";"))
                        {
                            identitySelect = ";" + identitySelect;
                        }

                        var incValue = PropertyValueHelper.NewValue(context.Database.ExecuteScalar <int>(sql + identitySelect, context.Parameters));
                        entity.InternalSetValue(incProperty, incValue);
                        return(!incValue.IsNullOrEmpty());
                    }
                    else
                    {
                        //使用生成器生成值
                        var generator = context.Database.Provider.GetService <IGeneratorProvider>();
                        if (generator != null)
                        {
                            var metadata = EntityMetadataUnity.GetEntityMetadata(entityType);
                            var inc      = generator.GenerateValue(context.Database, context.Environment == null ? metadata.TableName : context.Environment.GetVariableTableName(metadata), incProperty.Info.FieldName);
                            entity.InternalSetValue(incProperty, inc);

                            parameters.Clear();
                            sql = EntityPersistentQueryBuilder.BuidCreateQuery(context, entity);

                            return(context.Database.ExecuteNonQuery(sql, context.Parameters) > 0);
                        }
                    }
                }

                return(database.ExecuteNonQuery(sql, parameters) > 0);
            }

            return(false);
        }
コード例 #21
0
            protected override Expression VisitMember(MemberExpression memberExp)
            {
                var ex = Visit(memberExp.Expression);

                var member = memberExp.Member;
                var p      = PropertyUnity.GetProperty(member.DeclaringType, member.Name);

                if (p != null && p is IPropertyLazy)
                {
                    members.Add(member);
                }

                return(memberExp);
            }
コード例 #22
0
        /// <summary>
        /// 获取实体指定属性修改前的值。
        /// </summary>
        /// <param name="entity">当前的实体对象。</param>
        /// <param name="propertyName">属性名称。</param>
        /// <returns></returns>
        public static PropertyValue GetOldValue(this IEntity entity, string propertyName)
        {
            if (entity.EntityState == EntityState.Attached ||
                entity.EntityState == EntityState.Modified)
            {
                var property = PropertyUnity.GetProperty(entity.EntityType, propertyName);
                if (property != null)
                {
                    return(entity.GetOldValue(property));
                }
            }

            return(PropertyValue.Empty);
        }
コード例 #23
0
ファイル: EntityExtension.cs プロジェクト: zhangbo27/fireasy
        /// <summary>
        /// 获取实体指定属性修改前的值。
        /// </summary>
        /// <param name="entity">当前的实体对象。</param>
        /// <param name="propertyName">属性名称。</param>
        /// <returns></returns>
        public static PropertyValue GetOldValue(this IEntity entity, string propertyName)
        {
            if (entity.EntityState == EntityState.Attached ||
                entity.EntityState == EntityState.Modified)
            {
                var property = PropertyUnity.GetProperty(entity.EntityType, propertyName);
                var ext      = entity as IEntityStatefulExtension;
                if (property != null && ext != null)
                {
                    return(ext.GetOldValue(property));
                }
            }

            return(null);
        }
コード例 #24
0
        bool IDeserializeProcessor.SetValue(string name, object value)
        {
            if (EntityDeserializeProcessorScope.Current == null)
            {
                return(false);
            }

            var property = PropertyUnity.GetProperty(_entityType, name);

            if (property != null)
            {
                InitializeValue(property, PropertyValue.NewValue(value, property.Type));
                return(true);
            }

            return(false);
        }
コード例 #25
0
        /// <summary>
        /// 异步的,根据实体的状态,插入或更新实体对象。
        /// </summary>
        /// <param name="entity">要保存的实体对象。</param>
        /// <param name="cancellationToken">取消操作的通知。</param>
        /// <returns>影响的实体数。</returns>
        public async Task <int> InsertOrUpdateAsync(TEntity entity, CancellationToken cancellationToken = default)
        {
            Guard.ArgumentNull(entity, nameof(entity));

            var properties = PropertyUnity.GetPrimaryProperties(typeof(TEntity));
            var isNew      = entity.EntityState == EntityState.Attached;

            if (isNew && properties.Any(s => !PropertyValue.IsEmptyOrDefault(entity.GetValue(s))))
            {
                var parExp    = Expression.Parameter(typeof(TEntity), "s");
                var equalExp  = properties.Select(s => Expression.Equal(Expression.MakeMemberAccess(parExp, s.Info.ReflectionInfo), Expression.Constant(entity.GetValue(s)))).Aggregate(Expression.And);
                var lambdaExp = Expression.Lambda <Func <TEntity, bool> >(equalExp, parExp);
                isNew = !this.Any(lambdaExp);
            }

            return(await(isNew ? InsertAsync(entity, cancellationToken) : UpdateAsync(entity, cancellationToken)));
        }
コード例 #26
0
ファイル: EntityExtension.cs プロジェクト: zhangbo27/fireasy
        /// <summary>
        /// 将一个实体对象添加到 <see cref="DataTable"/> 对象里,该 <see cref="DataTable"/> 的结构必须保证与实体结构相符。
        /// </summary>
        /// <param name="entity">当前的实体对象。</param>
        /// <param name="table">一个使用 <see cref="Construct"/> 构造的 <see cref="DataTable"/>。</param>
        public static void Putin(this IEntity entity, DataTable table)
        {
            Guard.ArgumentNull(entity, "entity");
            Guard.ArgumentNull(table, "table");

            var properties = PropertyUnity.GetPersistentProperties(entity.EntityType)
                             .Where(s => table.Columns.Contains(s.Name)).ToList();

            var count = properties.Count;
            var data  = new object[count];

            for (var i = 0; i < count; i++)
            {
                var value = entity.InternalGetValue(properties[i]);
                data[i] = PropertyValue.IsNullOrEmpty(value) ? DBNull.Value : value.GetStorageValue();
            }

            table.Rows.Add(data);
        }
コード例 #27
0
        /// <summary>
        /// 通过主键值使对象正常化。
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="keyValues">主键值数组。</param>
        /// <returns></returns>
        public static T Normalize <T>(this T entity, params PropertyValue[] keyValues) where T : IEntity
        {
            var primaryKeys = PropertyUnity.GetPrimaryProperties(entity.EntityType).ToArray();

            if (primaryKeys.Length != 0 && keyValues == null ||
                primaryKeys.Length != keyValues.Length)
            {
                throw new Exception(SR.GetString(SRKind.DisaccordArgument, primaryKeys.Length, keyValues.Length));
            }

            for (var i = 0; i < primaryKeys.Length; i++)
            {
                entity.InitializeValue(primaryKeys[i], keyValues[i]);
            }

            entity.SetState(EntityState.Modified);

            return(entity);
        }
コード例 #28
0
        /// <summary>
        /// 使用主键和外键对应构造一对多的关系。
        /// </summary>
        /// <param name="relProperty"></param>
        /// <param name="thisType"></param>
        /// <param name="otherType"></param>
        /// <returns></returns>
        private static RelationshipMetadata MakeRelationshipMetadata(RelationProperty relProperty, Type thisType, Type otherType)
        {
            //是否使用了 ForeignKeyAttribute 来指定对应的外键
            var assignAttr = relProperty.Info.ReflectionInfo.GetCustomAttributes <RelationshipAssignAttribute>().FirstOrDefault();

            if (assignAttr != null)
            {
                var fkPro = PropertyUnity.GetProperty(otherType, assignAttr.ForeignKey);
                var pkPro = PropertyUnity.GetProperty(thisType, assignAttr.PrimaryKey);
                if (fkPro != null && pkPro != null)
                {
                    var key = new RelationshipKey {
                        ThisKey = pkPro.Name, ThisProperty = pkPro, OtherKey = fkPro.Name, OtherProperty = fkPro
                    };
                    return(new RelationshipMetadata(thisType, otherType, RelationshipStyle.One2Many, RelationshipSource.AutomaticallyAssign, new[] { key }));
                }
            }

            //使用名称相同的主键进行匹配
            var pks = PropertyUnity.GetPrimaryProperties(thisType).ToList();

            if (pks.Count > 0)
            {
                var fks  = pks.Select(s => PropertyUnity.GetProperty(otherType, s.Name)).ToList();
                var keys = new RelationshipKey[pks.Count];
                for (var i = 0; i < pks.Count; i++)
                {
                    if (fks[i] == null)
                    {
                        throw new Exception();
                    }

                    keys[i] = new RelationshipKey {
                        ThisKey = pks[i].Name, ThisProperty = pks[i], OtherKey = fks[i].Name, OtherProperty = fks[i]
                    };
                }

                return(new RelationshipMetadata(thisType, otherType, RelationshipStyle.One2Many, RelationshipSource.AutomaticallyAssign, keys));
            }

            return(null);
        }
コード例 #29
0
        private void AttachRequiredProperties(TEntity entity)
        {
            var pkValues = new List <PropertyValue>();

            foreach (var pkProperty in PropertyUnity.GetPrimaryProperties(typeof(TEntity)))
            {
                pkValues.Add(entity.GetValue(pkProperty));
            }

            var oldEntity = repository.Get(pkValues.ToArray());

            if (oldEntity == null)
            {
                return;
            }

            if (metaTree.InnerSign != null && !entity.IsModified(metaTree.InnerSign.Name))
            {
                entity.InitializeValue(metaTree.InnerSign, oldEntity.GetValue(metaTree.InnerSign));
            }

            if (metaTree.Name != null && !entity.IsModified(metaTree.Name.Name))
            {
                entity.InitializeValue(metaTree.Name, oldEntity.GetValue(metaTree.Name));
            }

            if (metaTree.FullName != null && !entity.IsModified(metaTree.FullName.Name))
            {
                entity.InitializeValue(metaTree.FullName, oldEntity.GetValue(metaTree.FullName));
            }

            if (metaTree.Order != null && !entity.IsModified(metaTree.Order.Name))
            {
                entity.InitializeValue(metaTree.Order, oldEntity.GetValue(metaTree.Order));
            }

            if (metaTree.Level != null && !entity.IsModified(metaTree.Level.Name))
            {
                entity.InitializeValue(metaTree.Level, oldEntity.GetValue(metaTree.Level));
            }
        }
コード例 #30
0
        /// <summary>
        /// 获取可以组织到查询里的属性。
        /// </summary>
        /// <param name="metadata"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        internal static Expression AddUseableSelectExpression <T>(EntityTreeMetadata metadata, Expression source)
        {
            var parExp  = Expression.Parameter(typeof(T), "s");
            var members = new List <MemberBinding>();

            foreach (var pkProperty in PropertyUnity.GetPrimaryProperties(typeof(T)))
            {
                if (pkProperty != metadata.InnerSign)
                {
                    members.Add(Expression.Bind(pkProperty.Info.ReflectionInfo, Expression.MakeMemberAccess(parExp, pkProperty.Info.ReflectionInfo)));
                }
            }

            members.Add(Expression.Bind(metadata.InnerSign.Info.ReflectionInfo, Expression.MakeMemberAccess(parExp, metadata.InnerSign.Info.ReflectionInfo)));

            if (metadata.Name != null)
            {
                members.Add(Expression.Bind(metadata.Name.Info.ReflectionInfo, Expression.MakeMemberAccess(parExp, metadata.Name.Info.ReflectionInfo)));
            }

            if (metadata.FullName != null)
            {
                members.Add(Expression.Bind(metadata.FullName.Info.ReflectionInfo, Expression.MakeMemberAccess(parExp, metadata.FullName.Info.ReflectionInfo)));
            }

            if (metadata.Order != null)
            {
                members.Add(Expression.Bind(metadata.Order.Info.ReflectionInfo, Expression.MakeMemberAccess(parExp, metadata.Order.Info.ReflectionInfo)));
            }

            if (metadata.Level != null)
            {
                members.Add(Expression.Bind(metadata.Level.Info.ReflectionInfo, Expression.MakeMemberAccess(parExp, metadata.Level.Info.ReflectionInfo)));
            }

            var mbrInit   = Expression.MemberInit(Expression.New(typeof(T)), members);
            var lambdaExp = Expression.Lambda(mbrInit, parExp);

            return(Expression.Call(typeof(Queryable), "Select", new[] { typeof(T), typeof(T) }, new[] { source, lambdaExp }));
        }