예제 #1
0
        object DeserializeDictionary(object inInstance, IKey inKey, Type declaredType, int inInheriteDeep, int inStructDeep, ILogPrinter inLogger)
        {
            Type[] gen_args = declaredType.GetGenericArguments();
            if (gen_args.Length < 2)
            {
                LogError(inLogger, string.Format("DeserializeDictionary: Generic Arguments are None. Type {0}", declaredType.Name));
                return(inInstance);
            }

            object instance = inInstance;

            // Instantiate if necessary
            if (instance == null)
            {
                instance = _reflectionProvider.Instantiate(declaredType, inLogger);
            }

            var dictionary = instance as IDictionary;

            Type keyDeclaredType   = gen_args[0];
            Type valueDeclaredType = gen_args[1];

            IKey tree_key = inKey.GetChild("BaseDictionary");

            if (tree_key == null)
            {
                tree_key = inKey;
            }

            for (int i = 0; i < tree_key.GetChildCount(); ++i)
            {
                IKey sub_key = tree_key.GetChild(i);

                object dic_key;
                if (!ReflectionHelper.StringToAtomicValue(sub_key.GetName(), keyDeclaredType, out dic_key, _reflectionProvider, inLogger))
                {
                    LogError(inLogger, string.Format("SubKey {0} [{3}] for dictionary with key type {1} can't convert value {2}",
                                                     tree_key, keyDeclaredType.Name, sub_key.GetName(), tree_key.GetPath()));
                }
                else
                {
                    object dic_value = DeserializeInternal(null, sub_key, valueDeclaredType, 0, inStructDeep + 1, inLogger);

                    if (dictionary.Contains(dic_key))
                    {
                        dictionary.Remove(dic_key);
                    }
                    dictionary.Add(dic_key, dic_value);
                }
            }
            return(instance);
        }
예제 #2
0
        /// <summary>
        ///     <para>
        ///         Finds the first <see cref="IKey" /> that is mapped to the same constraint in a shared table-like object.
        ///     </para>
        ///     <para>
        ///         This method is typically used by database providers (and other extensions). It is generally
        ///         not used in application code.
        ///     </para>
        /// </summary>
        /// <param name="key"> The key. </param>
        /// <param name="storeObject"> The identifier of the containing store object. </param>
        /// <returns> The key found, or <see langword="null" /> if none was found.</returns>
        public static IKey FindSharedObjectRootKey([NotNull] this IKey key, StoreObjectIdentifier storeObject)
        {
            Check.NotNull(key, nameof(key));

            var keyName = key.GetName(storeObject);
            var rootKey = key;

            // Limit traversal to avoid getting stuck in a cycle (validation will throw for these later)
            // Using a hashset is detrimental to the perf when there are no cycles
            for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
            {
                var linkedKey = rootKey.DeclaringEntityType
                                .FindRowInternalForeignKeys(storeObject)
                                .SelectMany(fk => fk.PrincipalEntityType.GetKeys())
                                .FirstOrDefault(k => k.GetName(storeObject) == keyName);
                if (linkedKey == null)
                {
                    break;
                }

                rootKey = linkedKey;
            }

            return(rootKey == key ? null : rootKey);
        }
예제 #3
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public static bool AreCompatible(
            [NotNull] this IKey key,
            [NotNull] IKey duplicateKey,
            StoreObjectIdentifier storeObject,
            bool shouldThrow)
        {
            if (!key.Properties.Select(p => p.GetColumnName(storeObject))
                .SequenceEqual(duplicateKey.Properties.Select(p => p.GetColumnName(storeObject))))
            {
                if (shouldThrow)
                {
                    throw new InvalidOperationException(
                              RelationalStrings.DuplicateKeyColumnMismatch(
                                  key.Properties.Format(),
                                  key.DeclaringEntityType.DisplayName(),
                                  duplicateKey.Properties.Format(),
                                  duplicateKey.DeclaringEntityType.DisplayName(),
                                  key.DeclaringEntityType.GetSchemaQualifiedTableName(),
                                  key.GetName(storeObject),
                                  key.Properties.FormatColumns(storeObject),
                                  duplicateKey.Properties.FormatColumns(storeObject)));
                }

                return(false);
            }

            return(true);
        }
예제 #4
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public static bool AreCompatibleForSqlServer(
            [NotNull] this IKey key,
            [NotNull] IKey duplicateKey,
            StoreObjectIdentifier storeObject,
            bool shouldThrow)
        {
            if (key.IsClustered(storeObject)
                != duplicateKey.IsClustered(storeObject))
            {
                if (shouldThrow)
                {
                    throw new InvalidOperationException(
                              SqlServerStrings.DuplicateKeyMismatchedClustering(
                                  key.Properties.Format(),
                                  key.DeclaringEntityType.DisplayName(),
                                  duplicateKey.Properties.Format(),
                                  duplicateKey.DeclaringEntityType.DisplayName(),
                                  storeObject.DisplayName(),
                                  key.GetName(storeObject)));
                }

                return(false);
            }

            return(true);
        }
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public static bool AreCompatibleForSqlServer(
            [NotNull] this IKey key,
            [NotNull] IKey duplicateKey,
            [NotNull] string tableName,
            [CanBeNull] string schema,
            bool shouldThrow)
        {
            if (key.IsClustered(tableName, schema)
                != duplicateKey.IsClustered(tableName, schema))
            {
                if (shouldThrow)
                {
                    throw new InvalidOperationException(
                              SqlServerStrings.DuplicateKeyMismatchedClustering(
                                  key.Properties.Format(),
                                  key.DeclaringEntityType.DisplayName(),
                                  duplicateKey.Properties.Format(),
                                  duplicateKey.DeclaringEntityType.DisplayName(),
                                  tableName,
                                  key.GetName(tableName, schema)));
                }

                return(false);
            }

            return(true);
        }
예제 #6
0
파일: TreeKeys.cs 프로젝트: Isuroku/Cascade
 bool CheckNameForChild(string inName)
 {
     for (int i = 0; i < _keys.Count; i++)
     {
         IKey k = _keys[i];
         if (string.Equals(k.GetName(), inName, StringComparison.InvariantCulture))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #7
0
파일: TreeKeys.cs 프로젝트: Isuroku/Cascade
        bool CheckNameByParent(string inName)
        {
            if (Parent == null)
            {
                return(true);
            }

            for (int i = 0; i < Parent._keys.Count; i++)
            {
                IKey k = Parent._keys[i];
                if (string.Equals(k.GetName(), inName, StringComparison.InvariantCulture))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #8
0
        void AddToTree(IKey key, TreeNodeCollection nc)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < key.GetValuesCount(); i++)
            {
                IKeyValue value = key.GetValue(i);

                string val_comments = string.Empty;
                if (!string.IsNullOrEmpty(value.Comments))
                {
                    val_comments = string.Format("[//{0}]", value.Comments);
                }

                sb.AppendFormat("{0}{1}, ", value, val_comments);
            }

            string arr_flag = string.Empty;

            if (key.IsArrayKey())
            {
                arr_flag = "[a]";
            }

            string key_comments = string.Empty;

            if (!string.IsNullOrEmpty(key.Comments))
            {
                key_comments = string.Format(" //{0}", key.Comments);
            }

            TreeNode tn = new TreeNode(string.Format("{0}{1}: {2}{3}", key.GetName(), arr_flag, sb, key_comments));

            nc.Add(tn);

            for (int i = 0; i < key.GetChildCount(); i++)
            {
                IKey el = key.GetChild(i);
                AddToTree(el, tn.Nodes);
            }
        }
예제 #9
0
파일: TreeKeys.cs 프로젝트: Isuroku/Cascade
        EKeyOpResult IsKeyAddable(IKey inNewChild)
        {
            if (!(inNewChild is CKey))
            {
                return(EKeyOpResult.UnnativeKey);
            }

            for (int i = 0; i < _keys.Count; i++)
            {
                IKey k = _keys[i];
                if (k == inNewChild)
                {
                    return(EKeyOpResult.AlreadyPresent);
                }

                if (string.Equals(k.GetName(), inNewChild.GetName(), StringComparison.InvariantCulture))
                {
                    return(EKeyOpResult.DublicateName);
                }
            }

            return(EKeyOpResult.OK);
        }
        private void GenerateKey(IKey key, IEntityType entityType, bool useDataAnnotations)
        {
            if (key == null)
            {
                var line = new List <string>
                {
                    $".{nameof(EntityTypeBuilder.HasNoKey)}()"
                };

                this.AppendMultiLineFluentApi(entityType, line);

                return;
            }

            var annotations = key.GetAnnotations().ToList();

            var explicitName = key.GetName() != key.GetDefaultName();

            RemoveAnnotation(ref annotations, RelationalAnnotationNames.Name);

            if (key.Properties.Count == 1 &&
                annotations.Count == 0)
            {
                if (key is Key concreteKey &&
                    key.Properties.SequenceEqual(
                        KeyDiscoveryConvention.DiscoverKeyProperties(
                            concreteKey.DeclaringEntityType,
                            concreteKey.DeclaringEntityType.GetProperties())))
                {
                    return;
                }

                if (!explicitName &&
                    useDataAnnotations)
                {
                    return;
                }
            }

            var lines = new List <string>
            {
                $".{nameof(EntityTypeBuilder.HasKey)}(e => {GenerateLambdaToKey(key.Properties, "e")})"
            };

            if (explicitName)
            {
                lines.Add(
                    $".{nameof(RelationalKeyBuilderExtensions.HasName)}" +
                    $"({this._code.Literal(key.GetName())})");
            }

            var annotationsToRemove = new List <IAnnotation>();

            foreach (var annotation in annotations)
            {
                if (annotation.Value == null ||
                    this._annotationCodeGenerator.IsHandledByConvention(key, annotation))
                {
                    annotationsToRemove.Add(annotation);
                }
                else
                {
                    var methodCall = this._annotationCodeGenerator.GenerateFluentApi(key, annotation);
                    if (methodCall != null)
                    {
                        lines.Add(this._code.Fragment(methodCall));
                        annotationsToRemove.Add(annotation);
                    }
                }
            }

            lines.AddRange(this.GenerateAnnotations(annotations.Except(annotationsToRemove)));

            this.AppendMultiLineFluentApi(key.DeclaringEntityType, lines);
        }
        private void GenerateKey(IKey key, IEntityType entityType, bool useDataAnnotations, IndentedStringBuilder sb)
        {
            if (key == null)
            {
                if (!useDataAnnotations)
                {
                    var line = new List <string> {
                        $".{nameof(EntityTypeBuilder.HasNoKey)}()"
                    };

                    AppendMultiLineFluentApi(entityType, line, sb);
                }

                return;
            }

            var annotations = AnnotationCodeGenerator
                              .FilterIgnoredAnnotations(key.GetAnnotations())
                              .ToDictionary(a => a.Name, a => a);

            AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(key, annotations);

            var explicitName = key.GetName() != key.GetDefaultName();

            annotations.Remove(RelationalAnnotationNames.Name);

            if (key.Properties.Count == 1 &&
                annotations.Count == 0)
            {
                if (key is Key concreteKey &&
                    key.Properties.SequenceEqual(
                        KeyDiscoveryConvention.DiscoverKeyProperties(
                            concreteKey.DeclaringEntityType,
                            concreteKey.DeclaringEntityType.GetProperties())))
                {
                    return;
                }

                if (!explicitName &&
                    useDataAnnotations)
                {
                    return;
                }
            }

            var lines = new List <string>
            {
                $".{nameof(EntityTypeBuilder.HasKey)}(e => {GenerateLambdaToKey(key.Properties, "e", EntityTypeTransformationService.TransformPropertyName)})"
            };

            if (explicitName)
            {
                lines.Add(
                    $".{nameof(RelationalKeyBuilderExtensions.HasName)}" +
                    $"({CSharpHelper.Literal(key.GetName())})");
            }

            lines.AddRange(
                AnnotationCodeGenerator.GenerateFluentApiCalls(key, annotations).Select(m => CSharpHelper.Fragment(m))
                .Concat(GenerateAnnotations(annotations.Values)));

            AppendMultiLineFluentApi(key.DeclaringEntityType, lines, sb);
        }
 private string GetKeyName(IKey key) => key?.GetName();
 /// <summary>
 ///     Returns the key constraint name for this key.
 /// </summary>
 /// <param name="key"> The key. </param>
 /// <returns> The key constraint name for this key. </returns>
 public static string GetName([NotNull] this IKey key)
 => key.GetName(StoreObjectIdentifier.Table(key.DeclaringEntityType.GetTableName(), key.DeclaringEntityType.GetSchema()));
예제 #14
0
 /// <summary>
 ///     Returns the key constraint name for this key.
 /// </summary>
 /// <param name="key"> The key. </param>
 /// <returns> The key constraint name for this key. </returns>
 public static string GetName([NotNull] this IKey key)
 => key.GetName(key.DeclaringEntityType.GetTableName(), key.DeclaringEntityType.GetSchema());
예제 #15
0
        public IEnumerable <Attribute> GetAnnotationContract(IRelationMetadata metadata)
        {
            IEntityType entity       = this.entities.FirstOrDefault(e => e.ClrType == metadata.Type);
            IEntityType parentEntity = this.entities.FirstOrDefault(e => e.ClrType == metadata.Parent?.Type);
            IProperty   property     = parentEntity?.GetProperties().FirstOrDefault(p => p.Name == metadata.Member?.Name);

            IAnnotation[] propertyAnnotations = property?.GetAnnotations().ToArray() ?? new IAnnotation[0];
#if NETSTANDARD2_0
            IKey primaryKey = property?.GetContainingPrimaryKey();
#elif NETSTANDARD2_1 || NETCOREAPP3_0
            IKey primaryKey = property?.FindContainingPrimaryKey();
#endif
            IForeignKey[] foreignKeys = property?.GetContainingForeignKeys().ToArray() ?? new IForeignKey[0];


            if (entity == null && property == null)
            {
                return(null);
            }

#if NETSTANDARD2_0
            string tableName  = entity?.Relational()?.TableName;
            string schemaName = entity?.Relational()?.Schema;
            string columnName = property?.Relational()?.ColumnName;
            string keyName    = primaryKey?.Relational()?.Name;
#elif NETSTANDARD2_1 || NETCOREAPP3_0
            string tableName  = entity?.GetTableName() ?? entity?.GetDefaultTableName();
            string schemaName = entity?.GetSchema() ?? entity?.GetDefaultSchema();
            string columnName = property?.GetColumnName() ?? property?.GetDefaultColumnName();
            string keyName    = primaryKey?.GetName();
#endif

            List <Attribute> annotations = new List <Attribute>();

            if (tableName != null && schemaName != null)
            {
                annotations.Add(new TableAttribute(schemaName, tableName));
            }
            else if (tableName != null)
            {
                annotations.Add(new TableAttribute(tableName));
            }

            if (columnName != null)
            {
                annotations.Add(new ColumnAttribute(columnName));
            }

            if (propertyAnnotations.Any(a => a.Name == "SqlServer:ValueGenerationStrategy" && a.Value?.ToString() == "IdentityColumn"))
            {
                annotations.Add(new IdAttribute());
            }

            if (keyName != null)
            {
                int index = primaryKey.Properties.ToList().IndexOf(property);

                annotations.Add(new KeyAttribute(keyName, index));
            }

            foreach (IForeignKey foreignKey in foreignKeys)
            {
#if NETSTANDARD2_0
                string principalName = foreignKey.PrincipalKey.Relational()?.Name;
                string foreignName   = foreignKey.Relational()?.Name;
                int    index         = foreignKey.Properties.ToList().IndexOf(property);
#elif NETSTANDARD2_1 || NETCOREAPP3_0
                string principalName = foreignKey.PrincipalKey.GetName();
                string foreignName   = foreignKey.GetConstraintName();
                int    index         = foreignKey.Properties.ToList().IndexOf(property);
#endif

                if (principalName != null)
                {
                    annotations.Add(new RefAttribute(principalName, index, foreignName));
                }
            }

            if (annotations.Any())
            {
                return(annotations);
            }

            return(null);
        }
예제 #16
0
        void SerializeClass(object instance, Type type, IKey inKey, int inInheriteDeep, ILogPrinter inLogger)
        {
            MethodInfo mi = type.GetMethod("SerializationToCscd", new Type[] { typeof(CascadeParser.IKey), typeof(CascadeParser.ILogPrinter) });

            if (mi != null)
            {
                if (string.IsNullOrEmpty(inKey.GetName()))
                {
                    inKey.SetName("Value");
                }

                mi.Invoke(instance, new object[] { inKey, inLogger });
                return;
            }

            MemberInfo[] member_infos = _reflectionProvider.GetSerializableMembers(type);
            foreach (MemberInfo memberInfo in member_infos)
            {
                object value = _reflectionProvider.GetValue(memberInfo, instance);
                if (value == null)
                {
                    continue;
                }

                SCustomMemberParams member_params = GetMemberParams(memberInfo);

                if (member_params.DefaultValue != null)
                {
                    if (member_params.DefaultValue.GetType() != value.GetType())
                    {
                        LogError(inLogger, string.Format("DefaultValue and member {2} of class {3} have difference types: {0} and {1}",
                                                         member_params.DefaultValue.GetType().Name,
                                                         value.GetType().Name,
                                                         member_params.Name,
                                                         type.Name));
                    }
                    else if (member_params.DefaultValue.Equals(value))
                    {
                        continue;
                    }
                }
                else if (ReflectionHelper.IsDefault(value, _reflectionProvider, inLogger))
                {
                    continue;
                }


                IKey child = inKey.CreateChildKey(member_params.ChangedName);

                Type real_type   = value.GetType();
                Type member_type = memberInfo.GetMemberType();

                if (member_params.Converter != null && member_params.Converter.CanConvert(real_type))
                {
                    member_params.Converter.WriteKey(child, value, inLogger);
                }
                else
                {
                    Serialize(value, real_type, child, 0, inLogger);
                }

                // Write the runtime type if different (except nullables since they get unboxed)
                if (real_type != member_type && !member_type.IsNullable())
                {
                    IKey obj_type_key = child.CreateChildKey("RealObjectType");
                    obj_type_key.AddValue(real_type.FullName);
                    obj_type_key.AddValue(real_type.Assembly.FullName);
                }
            }
        }