예제 #1
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, nameof(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);
        }
예제 #2
0
 string[] IEntity.GetModifiedProperties()
 {
     return((from s in InnerEntry.GetModifiedProperties()
             let p = PropertyUnity.GetProperty(_entityType, s)
                     where p != null && (!p.Info.IsPrimaryKey || (p.Info.IsPrimaryKey && p.Info.GenerateType == IdentityGenerateType.None))
                     select s).ToArray());
 }
예제 #3
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);
        }
예제 #4
0
            protected override MemberBinding VisitBinding(MemberBinding binding)
            {
                var assign = binding as MemberAssignment;

                if (assign == null)
                {
                    return(binding);
                }

                var propertyName = assign.Member.Name;
                var property     = PropertyUnity.GetProperty(typeof(TEntity), propertyName);

                if (property != null)
                {
                    if (condition.Length > 0)
                    {
                        condition.Append(" AND ");
                    }

                    var constExp = PartialEvaluator.Eval(assign.Expression) as ConstantExpression;
                    if (constExp.Type.IsStringOrDateTime())
                    {
                        condition.AppendFormat("{0} = '{1}'", property.Info.FieldName, constExp.Value);
                    }
                    else
                    {
                        condition.AppendFormat("{0} = {1}", property.Info.FieldName, constExp.Value);
                    }
                }

                return(binding);
            }
예제 #5
0
        void IInterceptor.Intercept(InterceptCallInfo info)
        {
            if (info.InterceptType == InterceptType.BeforeGetValue ||
                info.InterceptType == InterceptType.BeforeSetValue)
            {
                var entity     = info.Target as IEntity;
                var entityType = entity.EntityType;
                var property   = PropertyUnity.GetProperty(entityType, info.Member.Name);
                if (property == null)
                {
                    return;
                }

                info.Cancel = true;

                switch (info.InterceptType)
                {
                case InterceptType.BeforeGetValue:
                    var value = (entity as IPropertyAccessorBypass).GetValue(property);
                    if (value != null && !value.IsEmpty)
                    {
                        info.ReturnValue = value.GetStorageValue();
                    }
                    break;

                case InterceptType.BeforeSetValue:
                    (entity as IPropertyAccessorBypass).SetValue(property, info.Arguments[0]);
                    break;
                }
            }
        }
예제 #6
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);
        }
예제 #7
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));
        }
예제 #8
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);
        }
예제 #9
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);
        }
예제 #10
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);
            }
예제 #11
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);
        }
예제 #12
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);
                var ext      = entity as IEntityStatefulExtension;
                if (property != null && ext != null)
                {
                    return(ext.GetOldValue(property));
                }
            }

            return(null);
        }
예제 #13
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);
        }
예제 #14
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);
        }
예제 #15
0
        /// <summary>
        /// 判断指定名称的属性的值是否已经创建。
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <returns></returns>
        internal bool IsValueCreated(string propertyName)
        {
            var property = PropertyUnity.GetProperty(entityType, propertyName, true);

            if (property == null)
            {
                try
                {
                    return(entityType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance) != null);
                }
                catch
                {
                    return(false);
                }
            }

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

            return(true);
        }
예제 #16
0
        /// <summary>
        /// 克隆出一个新的实体对象。
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            var entity = _entityType.New <EntityObject>();

            entity.InitializeInstanceName((this.As <IEntityPersistentInstanceContainer>().InstanceName));
            entity.InitializeEnvironment(_environment);

            if (_entityType.IsNotCompiled())
            {
                foreach (var property in PropertyUnity.GetProperties(_entityType))
                {
                    var pv = GetValue(property);
                    entity.SetValue(property, pv);
                }
            }
            else
            {
                this.TryLockModifing(() =>
                {
                    InnerEntry.ForEach(k =>
                    {
                        var property = PropertyUnity.GetProperty(_entityType, k.Key);
                        if (property?.Info.IsPrimaryKey == true)
                        {
                            entity.InnerEntry.Initializate(k.Key, k.Value.GetCurrentValue());
                        }
                        else
                        {
                            entity.InnerEntry.Modify(k.Key, k.Value.GetCurrentValue());
                        }
                    });
                });
            }

            return(entity);
        }