Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="relProperty"></param>
        /// <param name="thisType"></param>
        /// <param name="otherType"></param>
        /// <returns></returns>
        private static RelationshipMetadata CachedRelationshipMetadata(RelationProperty relProperty, Type thisType, Type otherType)
        {
            if (relationCache.TryGetValue(thisType.Assembly, out SafetyDictionary <string, RelationshipMetadata> relations))
            {
                var key = string.Format("{0}:{1}:{2}",
                                        EntityMetadataUnity.GetEntityMetadata(thisType).TableName,
                                        EntityMetadataUnity.GetEntityMetadata(otherType).TableName, relProperty.Name);

                return(relations.GetOrAdd(key, () => MakeRelationshipMetadata(relProperty, thisType, otherType)));
            }

            return(null);
        }
Пример #2
0
        /// <summary>
        /// 根据规则获取实体关系。
        /// </summary>
        /// <param name="relProperty"></param>
        /// <returns></returns>
        private static RelationshipMetadata GetMetadataByAssignment(RelationProperty relProperty)
        {
            switch (relProperty.RelationalPropertyType)
            {
            case RelationPropertyType.Entity:
                return(CachedRelationshipMetadata(relProperty, relProperty.RelationalType, relProperty.EntityType));

            case RelationPropertyType.EntitySet:
                return(CachedRelationshipMetadata(relProperty, relProperty.EntityType, relProperty.RelationalType));

            case RelationPropertyType.RefProperty:
                break;
            }

            return(null);
        }
Пример #3
0
        /// <summary>
        /// 根据规则获取实体关系。
        /// </summary>
        /// <param name="relProperty"></param>
        /// <returns></returns>
        private static RelationshipMetadata GetMetadataByRule(RelationProperty relProperty)
        {
            switch (relProperty.RelationPropertyType)
            {
            case RelationPropertyType.Entity:
                return(MakeOne2ManyMetadataCached(relProperty.RelationType, relProperty.EntityType));

            case RelationPropertyType.EntitySet:
                return(MakeOne2ManyMetadataCached(relProperty.EntityType, relProperty.RelationType));

            case RelationPropertyType.RefProperty:
                var p = relProperty as ReferenceProperty;
                break;
            }

            return(null);
        }
Пример #4
0
    /// <summary>
    /// Copy ctor
    /// </summary>
    /// <param name="vCard">The vCard to clone.</param>
    private VCard(VCard vCard)
    {
        Version = vCard.Version;

        Func <ICloneable?, object?> cloner = Cloned;

        foreach (KeyValuePair <VCdProp, object> kvp in vCard._propDic)
        {
            Set(kvp.Key, kvp.Value switch
            {
                XmlProperty xmlProp => xmlProp.Clone(),
                IEnumerable <XmlProperty?> xmlPropEnumerable => xmlPropEnumerable.Select(cloner).Cast <XmlProperty?>().ToArray(),
                ProfileProperty profProp => profProp.Clone(),
                TextProperty txtProp => txtProp.Clone(),
                IEnumerable <TextProperty?> txtPropEnumerable => txtPropEnumerable.Select(cloner).Cast <TextProperty?>().ToArray(),
                DateTimeProperty dtTimeProp => dtTimeProp.Clone(),
                IEnumerable <DateTimeProperty?> dtTimePropEnumerable => dtTimePropEnumerable.Select(cloner).Cast <DateTimeProperty?>().ToArray(),
                AddressProperty adrProp => adrProp.Clone(),
                IEnumerable <AddressProperty?> adrPropEnumerable => adrPropEnumerable.Select(cloner).Cast <AddressProperty?>().ToArray(),
                NameProperty nameProp => nameProp.Clone(),
                IEnumerable <NameProperty?> namePropEnumerable => namePropEnumerable.Select(cloner).Cast <NameProperty?>().ToArray(),
                RelationProperty relProp => relProp.Clone(),
                IEnumerable <RelationProperty?> relPropEnumerable => relPropEnumerable.Select(cloner).Cast <RelationProperty?>().ToArray(),
                OrganizationProperty orgProp => orgProp.Clone(),
                IEnumerable <OrganizationProperty?> orgPropEnumerable => orgPropEnumerable.Select(cloner).Cast <OrganizationProperty?>().ToArray(),
                StringCollectionProperty strCollProp => strCollProp.Clone(),
                IEnumerable <StringCollectionProperty?> strCollPropEnumerable => strCollPropEnumerable.Select(cloner).Cast <StringCollectionProperty?>().ToArray(),
                GenderProperty sexProp => sexProp.Clone(),
                IEnumerable <GenderProperty?> sexPropEnumerable => sexPropEnumerable.Select(cloner).Cast <GenderProperty?>().ToArray(),
                GeoProperty geoProp => geoProp.Clone(),
                IEnumerable <GeoProperty?> geoPropEnumerable => geoPropEnumerable.Select(cloner).Cast <GeoProperty?>().ToArray(),
                DataProperty dataProp => dataProp.Clone(),
                IEnumerable <DataProperty?> dataPropEnumerable => dataPropEnumerable.Select(cloner).Cast <DataProperty?>().ToArray(),
                NonStandardProperty nStdProp => nStdProp.Clone(),
                IEnumerable <NonStandardProperty?> nStdPropEnumerable => nStdPropEnumerable.Select(cloner).Cast <NonStandardProperty?>().ToArray(),
                PropertyIDMappingProperty pidMapProp => pidMapProp.Clone(),
                IEnumerable <PropertyIDMappingProperty?> pidMapPropEnumerable => pidMapPropEnumerable.Select(cloner).Cast <PropertyIDMappingProperty?>().ToArray(),
                TimeZoneProperty tzProp => tzProp.Clone(),
                IEnumerable <TimeZoneProperty?> tzPropEnumerable => tzPropEnumerable.Select(cloner).Cast <TimeZoneProperty?>().ToArray(),

                ICloneable cloneable => cloneable.Clone(), // AccessProperty, KindProperty, TimeStampProperty, UuidProperty
                _ => kvp.Value
            });
Пример #5
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);
        }
Пример #6
0
        /// <summary>
        /// 将实体的所有主键值赋给关联的实体属性。
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="relationPro"></param>
        /// <param name="enumerable"></param>
        internal static void AttachPrimaryKeyValues(IEntity entity, RelationProperty relationPro, IEnumerable enumerable)
        {
            var relationKey = RelationshipUnity.GetRelationship(relationPro);

            if (relationKey == null)
            {
                return;
            }
            var action = GetAttachPrimaryKeyAction(enumerable.GetType().GetEnumerableElementType());

            foreach (IEntity item in enumerable)
            {
                if (item.EntityState != EntityState.Attached)
                {
                    continue;
                }
                foreach (var key in relationKey.Keys)
                {
                    action(item, key.OtherProperty, entity.InternalGetValue(key.ThisProperty));
                }
            }
        }
Пример #7
0
        /// <summary>
        /// 构造函数,
        /// 支持的格式有:
        /// this.LivingCityId=foreign.CityId
        /// LivingCityId=CityId
        /// this.CityId
        /// CityId
        /// </summary>
        public RelationAttribute(params string[] relationPropertys)
        {
            RelationPropertys = new RelationProperty[relationPropertys.Length];

            for (int i = 0; i < relationPropertys.Length; i++)
            {
                string   relationProperty      = relationPropertys[i];
                string[] relationPropertySplit = relationProperty.Split(SPLIT_CHARS_EQUALS, StringSplitOptions.RemoveEmptyEntries);
                if (relationPropertySplit.Length > 1)
                {
                    string[] leftSplit  = relationPropertySplit[0].Split(SPLIT_CHARS_POINT, StringSplitOptions.RemoveEmptyEntries);
                    string[] rightSplit = relationPropertySplit[1].Split(SPLIT_CHARS_POINT, StringSplitOptions.RemoveEmptyEntries);
                    string   left       = leftSplit.Length > 1 ? leftSplit[1] : leftSplit[0];
                    string   right      = rightSplit.Length > 1 ? rightSplit[1] : rightSplit[0];
                    RelationPropertys[i] = new RelationProperty(left, right);
                }
                else
                {
                    string[] leftSplit = relationPropertySplit[0].Split(SPLIT_CHARS_POINT, StringSplitOptions.RemoveEmptyEntries);
                    string   left      = leftSplit.Length > 1 ? leftSplit[1] : leftSplit[0];
                    RelationPropertys[i] = new RelationProperty(left, left);
                }
            }
        }
Пример #8
0
        private static RelationshipMetadata CheckSingleKey(IEnumerable <RelationshipMetadata> list, RelationProperty relationPro)
        {
            foreach (var item in list)
            {
                if (item.Style == RelationshipStyle.One2Many && item.ThisType == relationPro.RelationType && item.OtherType == relationPro.EntityType)
                {
                    if (!string.IsNullOrEmpty(relationPro.RelationKey))
                    {
                        if (item.Keys.Any(s => s.OtherKey == relationPro.RelationKey))
                        {
                            return(item);
                        }
                    }
                    else
                    {
                        return(item);
                    }
                }
                else if (item.Style == RelationshipStyle.Many2One && item.ThisType == relationPro.EntityType && item.OtherType == relationPro.RelationType)
                {
                    if (!string.IsNullOrEmpty(relationPro.RelationKey))
                    {
                        if (item.Keys.Any(s => s.ThisKey == relationPro.RelationKey))
                        {
                            return(item);
                        }
                    }
                    else
                    {
                        return(item);
                    }
                }
            }

            return(null);
        }
Пример #9
0
 private static RelationshipMetadata CheckSetKey(IEnumerable <RelationshipMetadata> list, RelationProperty relationPro)
 {
     return(list.FirstOrDefault(item =>
                                (item.ThisType == relationPro.EntityType &&
                                 item.OtherType == relationPro.RelationType &&
                                 item.Style == RelationshipStyle.One2Many) ||
                                (item.ThisType == relationPro.RelationType &&
                                 item.OtherType == relationPro.EntityType &&
                                 item.Style == RelationshipStyle.Many2One)));
 }
Пример #10
0
        internal static SqlCommand BuildEntitySetQuery(EntityQueryContext context, IEntity entity, RelationProperty relationProperty)
        {
            var relationKey = RelationshipUnity.GetRelationship(relationProperty);

            if (relationKey == null || relationKey.Style != RelationshipStyle.One2Many)
            {
                return(null);
            }

            var query = new EntityQueryBuilder(context, relationProperty.RelationType)
                        .Select().All().From();

            var valid = true;

            foreach (var key in relationKey.Keys)
            {
                var val = entity.InternalGetValue(key.ThisProperty);
                if (PropertyValue.IsNullOrEmpty(val) || !val.IsValid)
                {
                    valid = false;
                    continue;
                }

                query = query.And(key.OtherProperty, entity.InternalGetValue(key.ThisProperty));
            }

            if (!valid)
            {
                return(string.Empty);
            }

            return(query.ToSqlCommand());
        }
Пример #11
0
        internal static SqlCommand BuildEntityQuery(EntityQueryContext context, IEntity entity, RelationProperty relationProperty)
        {
            var relationKey = RelationshipUnity.GetRelationship(relationProperty);

            if (relationKey == null)
            {
                return(null);
            }

            Type relationType;
            Func <RelationshipKey, IProperty> func1, func2;

            if (entity.EntityType == relationKey.ThisType)
            {
                relationType = relationKey.OtherType;
                func1        = key => key.OtherProperty;
                func2        = key => key.ThisProperty;
            }
            else
            {
                relationType = relationKey.ThisType;
                func1        = key => key.ThisProperty;
                func2        = key => key.OtherProperty;
            }

            var query = new EntityQueryBuilder(context, relationType)
                        .Select().All().From();

            foreach (var key in relationKey.Keys)
            {
                var val = entity.InternalGetValue(func2(key));
                if (PropertyValue.IsNullOrEmpty(val) || !val.IsValid)
                {
                    return(string.Empty);
                }
                query = query.And(func1(key), val);
            }
            return(query.ToSqlCommand());
        }