public void JsonSerializationDeserializationTest()
        {
            var builder = new MetadataModelBuilder();

            builder.Entity <Invoice>();
            builder.Entity <Article>().HasOne(p => p.ArticleSettings).WithPrincipal();
            builder.ApplyConventions();

            MetadataModel model = null;

            using (var ms = new MemoryStream())
            {
                var json = new JsonSerializerSettings();
                json.Converters.Add(new LucileJsonInheritanceConverter());

                var serializer = JsonSerializer.Create(json);
                using (var streamWriter = new StreamWriter(ms, Encoding.UTF8, 512, true))
                {
                    serializer.Serialize(streamWriter, builder);
                }

                ms.Seek(0, SeekOrigin.Begin);

                using (var streamReader = new StreamReader(ms))
                    using (var jsonReader = new JsonTextReader(streamReader))
                    {
                        var newBuilder = serializer.Deserialize <MetadataModelBuilder>(jsonReader);
                        model = newBuilder.ToModel();
                    }
            }

            TestModelValidations.ValidateInvoiceArticleDefaultModel(model);
        }
Exemplo n.º 2
0
        public void MetadataModelBuilderFromModelTest()
        {
            var builder       = new MetadataModelBuilder();
            var entityBuilder = builder.Entity <Receipt>();

            entityBuilder.Property(p => p.Id).ValueGeneration = AutoGenerateValue.OnInsert;
            var nr = entityBuilder.Property(p => p.ReceiptNumber);

            nr.MaxLength = 20;
            nr.Nullable  = false;

            entityBuilder.PrimaryKey.Add("Id");

            var invoice = builder.Entity <Invoice>();

            invoice.BaseEntity = entityBuilder;
            var delivery = invoice.Property(p => p.ExpectedDeliveryDate);

            delivery.DateTimeType = DateTimePropertyType.DateTime;

            var oldModel = builder.ToModel();

            var newBuilder = new MetadataModelBuilder().FromModel(oldModel);
            var newModel   = newBuilder.ToModel();

            Assert.All(oldModel.Entities, p => Assert.NotNull(newModel.GetEntityMetadata(p.ClrType)));
            Assert.All(oldModel.Entities,
                       p =>
            {
                var newEntity = newModel.GetEntityMetadata(p.ClrType);
                Assert.All(p.GetProperties(), x => Assert.NotNull(newEntity.GetProperties().FirstOrDefault(y => y.Name == x.Name)));
            });
        }
Exemplo n.º 3
0
        public void DefaultStructureConventionTest()
        {
            var builder = new MetadataModelBuilder();

            builder.Entity <Invoice>();
            builder.Entity <Article>().HasOne(p => p.ArticleSettings).WithPrincipal();
            builder.ApplyConventions();
            TestModelValidations.ValidateInvoiceArticleDefaultModel(builder);
        }
Exemplo n.º 4
0
        public void TestCustomAccessor_ExpectsNoError()
        {
            var builder = new MetadataModelBuilder();

            builder.Entity <Article>();
            builder.Entity <ArticleName>();
            builder.Entity <Contact>();

            var model = builder.ApplyConventions().ToModel(new CustomAccessorFactory());

            Assert.NotNull(model);
        }
Exemplo n.º 5
0
        public void OneToOneWithConfigDefaultStructureConventionTest()
        {
            var builder = new MetadataModelBuilder();

            builder.Entity <Test1>().HasOne(p => p.Test2).WithPrincipal(p => p.Test1);
            builder.ApplyConventions();
            EntityMetadataBuilder entity = builder.Entity <Test1>();

            Assert.Equal(1, entity.PrimaryKey.Count);
            Assert.Equal("Id", entity.PrimaryKey.First());

            entity = builder.Entity <Test2>();

            Assert.Equal(1, entity.PrimaryKey.Count);
            Assert.Equal("Test2ID", entity.PrimaryKey.First());
        }
Exemplo n.º 6
0
        public IEnumerable <EntityMetadata> GetChildEntities(Type type)
        {
            var items = this._modelBuilder.Entities.Where(p => !p.IsExcluded && p.BaseEntity?.TypeInfo.ClrType == type);

            foreach (var item in items)
            {
                EntityMetadata result;
                if (Entities.TryGetValue(item.TypeInfo.ClrType, out result))
                {
                    yield return(result);
                }
                else
                {
                    yield return(new EntityMetadata(this, _modelBuilder.Entity(item.TypeInfo.ClrType)));
                }
            }
        }
Exemplo n.º 7
0
        public void MetadataModelBuilderGenericEntityTest()
        {
            var builder       = new MetadataModelBuilder();
            var entityBuilder = builder.Entity <Receipt>();

            Assert.Equal("Receipt", entityBuilder.Name);
            Assert.Equal(typeof(Receipt), entityBuilder.TypeInfo.ClrType);
        }
Exemplo n.º 8
0
        public void OneToOneDefaultStructureConventionTest()
        {
            var builder = new MetadataModelBuilder();
            var entity  = builder.Entity <Test1>();

            builder.ApplyConventions();
            var entity2 = builder.Entity <Test2>();

            var nav1 = entity.Navigation("Test2");
            var nav2 = entity2.Navigation("Test1");

            Assert.Equal(NavigationPropertyMultiplicity.ZeroOrOne, nav1.Multiplicity);
            Assert.Equal(NavigationPropertyMultiplicity.Many, nav1.TargetMultiplicity);

            Assert.Equal(NavigationPropertyMultiplicity.ZeroOrOne, nav2.Multiplicity);
            Assert.Equal(NavigationPropertyMultiplicity.Many, nav2.TargetMultiplicity);
        }
Exemplo n.º 9
0
        public void EntityMetadataBuilderReplacetItemWithNullTest()
        {
            var builder = new MetadataModelBuilder();

            var receiptBuilder = builder.Entity <Receipt>();

            receiptBuilder.HasMany(p => p.Details)
            .WithOne(p => p.Receipt)
            .HasForeignKey("ReceiptId");
            receiptBuilder.Property(p => p.Id).Nullable = false;
            receiptBuilder.PrimaryKey.Add("Id");

            builder.Entity <Invoice>().BaseEntity = receiptBuilder;

            var receiptDetailBuilder = builder.Entity <ReceiptDetail>();

            receiptDetailBuilder.PrimaryKey.Add("Id");
            receiptDetailBuilder.Property(p => p.Id).Nullable        = false;
            receiptDetailBuilder.Property(p => p.ReceiptId).Nullable = false;

            var model = builder.ToModel();

            var receipt = new Invoice {
                Id = Guid.NewGuid()
            };
            var rd1 = new ReceiptDetail {
                Id = Guid.NewGuid(), ReceiptId = receipt.Id
            };
            var rd2 = new ReceiptDetail {
                Id = Guid.NewGuid(), ReceiptId = receipt.Id
            };

            receipt.Details.AddRange(new[] { rd1, rd2 });

            var entity  = model.GetEntityMetadata(receipt);
            var details = entity.GetNavigations().First(p => p.Name == "Details");

            Assert.Equal(2, receipt.Details.Count);
            Assert.All(receipt.Details, p => Assert.NotNull(p));

            details.ReplaceItem(receipt, rd1, null);

            Assert.Single(receipt.Details);
            Assert.All(receipt.Details, p => Assert.NotNull(p));
        }
Exemplo n.º 10
0
        public void MetadataModelBuilderMaxLengthTest()
        {
            var builder       = new MetadataModelBuilder();
            var entityBuilder = builder.Entity <Receipt>();

            builder.ApplyConventions();

            Assert.Equal(100, entityBuilder.Property(c => c.ReceiptNumber).MaxLength);
        }
Exemplo n.º 11
0
        public void DefaultKeyConventionTest()
        {
            var builder = new MetadataModelBuilder();

            builder.Entity <Test1>().HasOne(p => p.Test2).WithPrincipal(p => p.Test1);
            builder.ApplyConventions();
            var entity  = builder.Entity <Test1>();
            var entity2 = builder.Entity <Test2>();

            var nav1 = entity.Navigation("Test2");
            var nav2 = entity2.Navigation("Test1");

            Assert.Equal(NavigationPropertyMultiplicity.ZeroOrOne, nav1.Multiplicity);
            Assert.Equal(NavigationPropertyMultiplicity.One, nav1.TargetMultiplicity);

            Assert.Equal(NavigationPropertyMultiplicity.One, nav2.Multiplicity);
            Assert.Equal(NavigationPropertyMultiplicity.ZeroOrOne, nav2.TargetMultiplicity);
        }
Exemplo n.º 12
0
        public void EntityMetadataBuilderGenericBlobProperty()
        {
            var builder = new MetadataModelBuilder();
            var prop    = builder.Entity <AllTypesEntity>()
                          .Property(p => p.BlobProperty);

            Assert.IsType <BlobPropertyBuilder>(prop);
            Assert.Equal("BlobProperty", prop.Name);
            Assert.True(prop.Nullable);
        }
Exemplo n.º 13
0
        public void EntityMetadataBuilderTextProperty()
        {
            var builder = new MetadataModelBuilder();
            var prop    = builder.Entity <Receipt>()
                          .Property("ReceiptNumber", typeof(string));

            Assert.IsType <TextPropertyBuilder>(prop);
            Assert.Equal("ReceiptNumber", prop.Name);
            Assert.True(prop.Nullable);
        }
Exemplo n.º 14
0
        public void EntityMetadataBuilderEnumProperty()
        {
            var builder = new MetadataModelBuilder();
            var prop    = builder.Entity <Receipt>()
                          .Property(p => p.ReceiptType);

            Assert.Equal("ReceiptType", prop.Name);
            Assert.Equal(NumericPropertyType.Byte, prop.UnderlyingNumericType);
            Assert.Equal(typeof(ReceiptType), prop.EnumTypeInfo.ClrType);
            Assert.False(prop.Nullable);

            prop = builder.Entity <Contact>()
                   .Property(p => p.ContactType);

            Assert.Equal("ContactType", prop.Name);
            Assert.Equal(NumericPropertyType.Int32, prop.UnderlyingNumericType);
            Assert.Equal(typeof(ContactType), prop.EnumTypeInfo.ClrType);
            Assert.True(prop.Nullable);
        }
Exemplo n.º 15
0
        public void GetEntityInheritenceTest()
        {
            var builder = new MetadataModelBuilder();
            var receipt = builder.Entity <Receipt>();
            var invoice = builder.Entity <Invoice>();

            invoice.BaseEntity = receipt;
            var order = builder.Entity <Order>();

            order.BaseEntity = invoice;

            var model = builder.ToModel();

            var invoiceInstance = new Invoice();
            var entity          = model.GetEntityMetadata(invoiceInstance);

            Assert.Equal("Invoice", entity.Name);
            entity = model.GetEntityMetadata <Order>();

            Assert.Equal("Order", entity.Name);
        }
        public void DataContractSerializationDeserializationTest()
        {
            var builder = new MetadataModelBuilder();

            builder.Entity <Invoice>();
            builder.Entity <Article>().HasOne(p => p.ArticleSettings).WithPrincipal();
            builder.ApplyConventions();

            MetadataModel model = null;

            using (var ms = new MemoryStream())
            {
                var ser = new DataContractSerializer(typeof(MetadataModelBuilder));
                ser.WriteObject(ms, builder);
                ms.Seek(0, SeekOrigin.Begin);
                var newBuilder = (MetadataModelBuilder)ser.ReadObject(ms);
                model = newBuilder.ToModel();
            }

            TestModelValidations.ValidateInvoiceArticleDefaultModel(model);
        }
Exemplo n.º 17
0
        public void InequalityTest()
        {
            var builder = new MetadataModelBuilder();

            builder.Entity <Invoice>().Property(p => p.ReceiptType);
            builder.Entity <Invoice>().Property(p => p.ReceiptNumber);
            builder.Entity <Invoice>().Property(p => p.Id);
            builder.Entity <Invoice>().Property(p => p.ReceiptDate);
            builder.Entity <Invoice>().PrimaryKey.Add("ReceiptNumber");
            builder.Entity <Invoice>().PrimaryKey.Add("ReceiptType");
            var model = builder.ToModel();

            var entity  = model.GetEntityMetadata <Invoice>();
            var invoice = new Invoice {
                ReceiptNumber = "TestNumber", ReceiptType = ReceiptType.Invoice
            };

            var key   = entity.GetPrimaryKeyObject(invoice);
            var typed = key as EntityKey <string, ReceiptType>;

            var keycompare = new EntityKey <string, ReceiptType>(entity)
            {
                Value0 = "Bla",
                Value1 = ReceiptType.Invoice
            };

            Assert.NotEqual(key.GetHashCode(), keycompare.GetHashCode());
            Assert.NotEqual(key, keycompare);
        }
Exemplo n.º 18
0
        public void GetMetadataPerformanceTest()
        {
            var builder = new MetadataModelBuilder();
            var receipt = builder.Entity <Receipt>();
            var invoice = builder.Entity <Invoice>();
            var order   = builder.Entity <Order>();

            invoice.Property(p => p.Id);
            invoice.PrimaryKey.Add("Id");

            var model = builder.ToModel();

            var inv = new Invoice {
                Id = Guid.NewGuid()
            };
            var ord = new Order {
                Id = Guid.NewGuid()
            };

            var sw = new Stopwatch();

            sw.Start();

            for (int i = 0; i < 2000000; i++)
            {
                if (i % 2 == 0)
                {
                    var entity = model.GetEntityMetadata(inv);
                }
                else
                {
                    var entity = model.GetEntityMetadata(ord);
                }
            }

            sw.Stop();

            Assert.True(sw.Elapsed.TotalSeconds < 1, "too slow");
        }
        public void ProtoBufSerializationDeserializationTest()
        {
            var builder = new MetadataModelBuilder();

            builder.Entity <Invoice>();
            builder.Entity <Article>().HasOne(p => p.ArticleSettings).WithPrincipal();
            builder.ApplyConventions();

            MetadataModel model = null;

            using (var ms = new MemoryStream())
            {
                ProtoBuf.Serializer.Serialize <MetadataModelBuilder>(ms, builder);

                ms.Seek(0, SeekOrigin.Begin);

                var newBuilder = ProtoBuf.Serializer.Deserialize <MetadataModelBuilder>(ms);
                model = newBuilder.ToModel();
            }

            TestModelValidations.ValidateInvoiceArticleDefaultModel(model);
        }
Exemplo n.º 20
0
        public void MetadataModelSortByDependencyTest()
        {
            var metadataModelBuilder  = new MetadataModelBuilder();
            var articleEntity         = metadataModelBuilder.Entity <Article>();
            var receiptEntity         = metadataModelBuilder.Entity <Receipt>();
            var receiptDetailEntity   = metadataModelBuilder.Entity <ReceiptDetail>();
            var articleSettingsEntity = metadataModelBuilder.Entity <ArticleSettings>();

            articleSettingsEntity.Property(p => p.Id);
            articleSettingsEntity.Property(p => p.Whatever);
            articleSettingsEntity.PrimaryKey.Add("Id");

            articleEntity.Property(p => p.Id);
            articleEntity.Property(p => p.Price);
            articleEntity.PrimaryKey.Add("Id");

            receiptEntity.Property(p => p.Id);
            receiptEntity.Property(p => p.ReceiptNumber);
            receiptEntity.PrimaryKey.Add("Id");

            receiptDetailEntity.Property(p => p.Id);
            receiptDetailEntity.Property(p => p.ReceiptId);
            receiptDetailEntity.Property(p => p.ArticleId);
            receiptDetailEntity.PrimaryKey.Add("Id");

            articleEntity.HasOne(p => p.ArticleSettings).WithPrincipal();
            receiptDetailEntity.HasOne(p => p.Receipt).WithMany(p => p.Details).HasForeignKey("ReceiptId");
            receiptDetailEntity.HasOne(p => p.Article).WithMany().HasForeignKey("ArticleId");

            var model = metadataModelBuilder.ToModel();

            var sorted = model.SortedByDependency();

            Assert.Contains(sorted.Take(2), p => p.Name == "Article");
            Assert.Contains(sorted.Take(2), p => p.Name == "Receipt");
            Assert.Contains(sorted.Skip(2), p => p.Name == "ArticleSettings");
            Assert.Contains(sorted.Skip(2), p => p.Name == "ReceiptDetail");
        }
Exemplo n.º 21
0
        public void TestNoneClrPropertiyInModel_UsePropertyMethod_ExpectsOK()
        {
            var modelBuilder = new MetadataModelBuilder();

            modelBuilder.Entity <Contact>()
            .Property <string>("NoneClrProperty");

            var model  = modelBuilder.ToModel();
            var entity = model.GetEntityMetadata <Contact>();

            var property = entity["NoneClrProperty"];

            Assert.NotNull(property);
        }
Exemplo n.º 22
0
        public void GetTargetNavigationPropertyPerformance()
        {
            var builder = new MetadataModelBuilder();

            var receiptBuilder = builder.Entity <Receipt>();

            receiptBuilder.HasMany(p => p.Details)
            .WithOne(p => p.Receipt)
            .HasForeignKey("ReceiptId");
            receiptBuilder.Property(p => p.Id).Nullable = false;
            receiptBuilder.PrimaryKey.Add("Id");

            builder.Entity <Invoice>().BaseEntity = receiptBuilder;

            var receiptDetailBuilder = builder.Entity <ReceiptDetail>();

            receiptDetailBuilder.PrimaryKey.Add("Id");
            receiptDetailBuilder.Property(p => p.Id).Nullable        = false;
            receiptDetailBuilder.Property(p => p.ReceiptId).Nullable = false;

            var model = builder.ToModel();

            var receipt = model.GetEntityMetadata <Receipt>();
            var details = receipt.GetNavigations().First(p => p.Name == "Details");

            var sw = new Stopwatch();

            sw.Start();
            for (int i = 0; i < 2000000; i++)
            {
                var targetProp = details.TargetNavigationProperty;
            }
            sw.Stop();

            Assert.True(sw.Elapsed.TotalSeconds < 1);
        }
        private static void ResolveNavigations(MetadataModelBuilder builder, IEnumerable <IStructureConvention> conventions, IEnumerable <Type> types)
        {
            var targetTypes = types.SelectMany(p => conventions.SelectMany(x => x.GetNavigations(p)?.Values ?? Enumerable.Empty <Type>())).Distinct();

            var missingTypes = targetTypes.Except(builder.Entities.Select(p => p.TypeInfo.ClrType)).ToList();

            if (missingTypes.Any())
            {
                foreach (var item in missingTypes)
                {
                    builder.Entity(item);
                }

                ResolveNavigations(builder, conventions, missingTypes);
            }
        }
Exemplo n.º 24
0
        public void TestNoneClrPropertiyInModel_UsePropertyNameProperty_ExpectsOK()
        {
            var modelBuilder = new MetadataModelBuilder();

            var entityBuilder = modelBuilder.Entity <Contact>();

            entityBuilder.Properties.Add(new TextPropertyBuilder {
                Name = "NoneClrProperty", PropertyType = new ClrTypeInfo(typeof(string))
            });

            var model  = modelBuilder.ToModel();
            var entity = model.GetEntityMetadata <Contact>();

            var property = entity["NoneClrProperty"];

            Assert.NotNull(property);
        }
Exemplo n.º 25
0
        private void BuildModel(out List <PropertyConfiguration> propConfigs, out List <SourceEntityConfiguration> sourceEntityConfigs, out Data.Metadata.EntityMetadata entity)
        {
            var entityModelBuilder = new MetadataModelBuilder();
            var entityBuilder      = entityModelBuilder.Entity <TResult>();

            propConfigs         = new List <PropertyConfiguration>();
            sourceEntityConfigs = _sourceBuilders.Select(p => p.Value.ToTarget()).ToList();
            foreach (var item in _propertyBuilders)
            {
                var expression = item.Value.MappedExpression;

                if (expression.Body.NodeType == ExpressionType.New || expression.Body.NodeType == ExpressionType.MemberInit)
                {
                    var nav = entityBuilder.Navigation(item.Value.PropertyName);
                }
                else
                {
                    entityBuilder.Property(item.Value.PropertyName, item.Value.PropertyType);
                    if (item.Value.IsPrimaryKey)
                    {
                        entityBuilder.PrimaryKey.Add(item.Value.PropertyName);
                    }
                }

                // TODO: Merge Metadata from mapped Properties
            }

            var model = entityModelBuilder.ToModel();

            entity = model.GetEntityMetadata <TResult>();
            foreach (var item in _propertyBuilders)
            {
                var prop   = entity[item.Value.PropertyName];
                var config = new PropertyConfiguration(prop, item.Value.Label, item.Value.CanAggregate, item.Value.CanFilter, item.Value.CanSort, item.Value.CustomFilterExpression, item.Value.MappedExpression, !IsSingleSourceQuery);
                propConfigs.Add(config);
            }
        }
Exemplo n.º 26
0
        private static MetadataModel GetModel()
        {
            var metadataModelBuilder = new MetadataModelBuilder();

            metadataModelBuilder.Exclude <EntityBase>();
            metadataModelBuilder.Entity <ArticleName>().PrimaryKey.AddRange(new[] { "ArticleId", "LanguageId" });
            var articleEntity = metadataModelBuilder.Entity <Article>();

            metadataModelBuilder.Entity <ReceiptDetail>();
            metadataModelBuilder.Entity <Invoice>().BaseEntity = metadataModelBuilder.Entity(typeof(Receipt));
            var contactSettings = metadataModelBuilder.Entity <ContactSettings>();

            articleEntity.HasOne(p => p.ArticleSettings).WithPrincipal();
            contactSettings.HasOne(p => p.Contact).WithDependant();

            metadataModelBuilder.ApplyConventions();

            var model = metadataModelBuilder.ToModel();

            return(model);
        }
        private static EntityMetadataBuilder FromEntityType(this MetadataModelBuilder builder, IEntityType entityType)
        {
            var entityBuilder = builder.Entity(entityType.ClrType);

            if (entityType.BaseType != null)
            {
                var baseEntityBuilder = builder.FromEntityType(entityType.BaseType);
                entityBuilder.BaseEntity = baseEntityBuilder;
            }

            var properties = entityType.GetProperties().Where(p => p.DeclaringEntityType == entityType);

            foreach (var prop in properties)
            {
                var propBuilder = entityBuilder.Property(prop.Name, prop.ClrType);
                propBuilder.Nullable = prop.IsNullable;
                if (prop.ValueGenerated == ValueGenerated.OnAdd)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.OnInsert;
                }
                else if (prop.ValueGenerated == ValueGenerated.OnAddOrUpdate)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.Both;
                }
#if NETSTANDARD2_0
                else if (prop.ValueGenerated == ValueGenerated.OnUpdate)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.Both;
                }
#endif

                if (propBuilder is TextPropertyBuilder textBuilder)
                {
                    textBuilder.MaxLength = prop.GetMaxLength();
                }
                else if (propBuilder is BlobPropertyBuilder blobPropertyBuilder)
                {
                    blobPropertyBuilder.MaxLength = prop.GetMaxLength();
                }
            }

            if (entityType.BaseType == null)
            {
                foreach (var pk in entityType.FindPrimaryKey().Properties)
                {
                    entityBuilder.PrimaryKey.Add(pk.Name);
                }
            }

            foreach (var nav in entityType.GetNavigations().Where(p => p.DeclaringEntityType == entityType))
            {
                NavigationPropertyBuilder navBuilder = null;
                var           inverse            = nav.FindInverse();
                Type          targetType         = nav.GetTargetType().ClrType;
                string        targetPropertyName = inverse?.Name;
                List <string> foreignKeys        = new List <string>();

                NavigationPropertyMultiplicity multiplicity       = NavigationPropertyMultiplicity.One;
                NavigationPropertyMultiplicity targetMultiplicity = NavigationPropertyMultiplicity.One;
                if (nav.IsCollection())
                {
                    multiplicity       = NavigationPropertyMultiplicity.Many;
                    targetMultiplicity = nav.ForeignKey.IsRequired ? NavigationPropertyMultiplicity.One : NavigationPropertyMultiplicity.ZeroOrOne;
                }
                else if (nav.IsDependentToPrincipal())
                {
                    multiplicity       = nav.ForeignKey.IsRequired ? NavigationPropertyMultiplicity.One : NavigationPropertyMultiplicity.ZeroOrOne;
                    targetMultiplicity = nav.ForeignKey.IsUnique ? NavigationPropertyMultiplicity.ZeroOrOne : NavigationPropertyMultiplicity.Many;

                    foreignKeys = nav.ForeignKey.Properties.Select(p => p.Name).ToList();
                }
                else
                {
                    multiplicity       = NavigationPropertyMultiplicity.ZeroOrOne;
                    targetMultiplicity = NavigationPropertyMultiplicity.One;
                }

                navBuilder = entityBuilder.Navigation(nav.Name);

                navBuilder.Nullable           = multiplicity == NavigationPropertyMultiplicity.ZeroOrOne;
                navBuilder.Multiplicity       = multiplicity;
                navBuilder.Target             = new ClrTypeInfo(targetType);
                navBuilder.TargetProperty     = targetPropertyName;
                navBuilder.TargetMultiplicity = targetMultiplicity;
                navBuilder.ForeignKey         = foreignKeys;
            }

            return(entityBuilder);
        }
        public static MetadataModelBuilder ApplyConventions(this MetadataModelBuilder builder, ConventionCollection conventions = null)
        {
            conventions = conventions ?? ConventionCollection.DefaultConventions;

            var structureConventions    = conventions.OfType <IStructureConvention>().ToList();
            var oldNavigationProperties = builder.Entities.SelectMany(p => p.Navigations).ToList();
            var added = new Dictionary <Type, List <NavigationPropertyBuilder> >();

            ResolveNavigations(builder, structureConventions, builder.Entities.Select(p => p.TypeInfo.ClrType).ToList());

            foreach (var entity in builder.Entities.Where(p => !p.IsExcluded))
            {
                foreach (var item in structureConventions.SelectMany(p => p.GetScalarProperties(entity.TypeInfo.ClrType)).Distinct())
                {
                    entity.Property(item.Key, item.Value);
                }
            }

            foreach (var entity in builder.Entities.Where(p => !p.IsExcluded))
            {
                foreach (var item in structureConventions.SelectMany(p => p.GetNavigations(entity.TypeInfo.ClrType)).Distinct())
                {
                    var nav = entity.Navigation(item.Key);

                    if (!oldNavigationProperties.Contains(nav))
                    {
                        if (!added.ContainsKey(entity.TypeInfo.ClrType))
                        {
                            added.Add(entity.TypeInfo.ClrType, new List <NavigationPropertyBuilder>());
                        }

                        added[entity.TypeInfo.ClrType].Add(nav);
                    }
                }
            }

            var entityConventions = conventions.OfType <IEntityConvention>().ToList();

            foreach (var item in builder.Entities)
            {
                entityConventions.ForEach(p => p.Apply(item));
            }

            foreach (var item in added)
            {
                var entity = builder.Entity(item.Key);
                foreach (var nav in item.Value.Where(p => p.Multiplicity != NavigationPropertyMultiplicity.Many && !p.ForeignKey.Any()))
                {
                    var fk = entity.Properties.Where(p => p.Name.Equals($"{nav.Name}Id", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                    if (fk != null)
                    {
                        nav.Multiplicity = fk.Nullable ? NavigationPropertyMultiplicity.ZeroOrOne : NavigationPropertyMultiplicity.One;
                        nav.ForeignKey.Add(fk.Name);
                    }
                }
            }

            foreach (var item in added)
            {
                foreach (var nav in item.Value.ToList())
                {
                    var target = builder.Entity(nav.Target.ClrType).Navigations
                                 .FirstOrDefault(p => p.Target.ClrType.IsAssignableFrom(item.Key) && p.TargetProperty == nav.Name);
                    if (target != null)
                    {
                        nav.Multiplicity       = target.TargetMultiplicity;
                        nav.TargetMultiplicity = target.Multiplicity;
                        nav.TargetProperty     = target.Name;
                        item.Value.Remove(nav);
                    }
                }

                foreach (var nav in item.Value.GroupBy(p => new { Type = p.Target.ClrType, IsCollection = p.Multiplicity == NavigationPropertyMultiplicity.Many }))
                {
                    if (nav.Count() > 1)
                    {
                        throw new ModelBuilderValidationExcpetion($"Multiple NavigationProperties for same target entity {nav.Key.Type} found. Use .Navigation() configuration on EntityMetadataBuilder.");
                    }

                    List <NavigationPropertyBuilder> target = new List <NavigationPropertyBuilder>();

                    if (added.ContainsKey(nav.First().Target.ClrType))
                    {
                        if (nav.First().Multiplicity == NavigationPropertyMultiplicity.Many)
                        {
                            target = added[nav.First().Target.ClrType].Where(p => p.Target.ClrType == item.Key && p.Multiplicity != NavigationPropertyMultiplicity.Many).ToList();
                        }
                        else
                        {
                            target = added[nav.First().Target.ClrType].Where(p => p.Target.ClrType == item.Key && p.Multiplicity == NavigationPropertyMultiplicity.Many).ToList();
                        }
                    }

                    if (!target.Any())
                    {
                        nav.First().TargetMultiplicity = nav.First().Multiplicity == NavigationPropertyMultiplicity.Many ? NavigationPropertyMultiplicity.ZeroOrOne : NavigationPropertyMultiplicity.Many;
                    }
                    else if (target.Count == 1)
                    {
                        nav.First().TargetMultiplicity = target.First().Multiplicity;
                        nav.First().TargetProperty     = target.First().Name;
                    }
                    else
                    {
                        throw new ModelBuilderValidationExcpetion($"Multiple NavigationProperties for same target entity {item.Key} found. Use .Navigation() configuration on EntityMetadataBuilder.");
                    }
                }
            }

            return(builder);
        }
        private static EntityMetadataBuilder FromEntityType(this MetadataModelBuilder builder, MetadataWorkspace metadata, EntityType entityType)
        {
            var objectItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace);
            var mapping = metadata.GetItems <EntityContainerMapping>(DataSpace.CSSpace)
                          .Single()
                          .EntitySetMappings
                          .SelectMany(p => p.EntityTypeMappings);

            var objectTypes = metadata.GetItems <EntityType>(DataSpace.OSpace);

            var objectType = objectTypes.Single(p => p.Name == entityType.Name);
            var clrType    = objectItemCollection.GetClrType(objectType);

            var entityBuilder = builder.Entity(clrType);

            if (entityType.BaseType != null)
            {
                var baseEntityBuilder = builder.FromEntityType(metadata, (EntityType)entityType.BaseType);
                entityBuilder.BaseEntity = baseEntityBuilder;
            }

            var propertyMappings = mapping.SelectMany(p => p.Fragments.SelectMany(x => x.PropertyMappings)).OfType <ScalarPropertyMapping>().ToList();

            var joined = from p in entityType.Properties.Where(p => p.DeclaringType == entityType)
                         join m in propertyMappings on p equals m.Property
                         select new { Property = p, Column = m.Column };

            foreach (var prop in joined)
            {
                var propertyClrType = metadata.GetClrTypeFromCSpaceType(prop.Property);

                var propBuilder = entityBuilder.Property(prop.Property.Name, propertyClrType);
                propBuilder.Nullable = prop.Property.Nullable;
                if (prop.Column.IsStoreGeneratedComputed)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.Both;
                }
                else if (prop.Column.IsStoreGeneratedIdentity)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.OnInsert;
                }

                propBuilder.HasDefaultValue = prop.Column.MetadataProperties.Any(p => p.IsAnnotation && p.Name.EndsWith(":" + DefaultValueAnnotation.AnnotationName, StringComparison.Ordinal));

                if (propBuilder is TextPropertyBuilder textBuilder)
                {
                    textBuilder.MaxLength = prop.Property.MaxLength;
                }
                else if (propBuilder is BlobPropertyBuilder blobPropertyBuilder)
                {
                    blobPropertyBuilder.MaxLength = prop.Property.MaxLength;
                }
            }

            if (entityType.BaseType == null)
            {
                foreach (var pk in entityType.KeyProperties)
                {
                    entityBuilder.PrimaryKey.Add(pk.Name);
                }
            }

            foreach (var nav in entityType.NavigationProperties.Where(p => p.DeclaringType == entityType))
            {
                NavigationPropertyBuilder navBuilder = null;

                ////var navpropMatch = from l in item.EntityMetadata.Properties.OfType<NavigationPropertyMetadata>()
                ////                   join r in item.EntityType.NavigationProperties on l.Name equals r.Name
                ////                   select new { Left = l, Right = r };

                ////foreach (var npmatch in navpropMatch)
                ////{
                ////    var test = entityTypes.SelectMany(p => p.NavigationProperties)
                ////                          .FirstOrDefault(p => p.ToEndMember == npmatch.Right.FromEndMember);

                var inverse = nav.ToEndMember.GetEntityType().NavigationProperties.FirstOrDefault(p => p.FromEndMember == nav.ToEndMember);

                ////var inverse = nav.ToEndMember.MetadataProperties.FirstOrDefault(p => p.Name == "ClrPropertyInfo")?.Value as PropertyInfo;

                var targetObjectType = objectTypes.Single(p => p.Name == nav.ToEndMember.GetEntityType().Name);
                var targetClrType    = objectItemCollection.GetClrType(targetObjectType);

                string        targetPropertyName = inverse?.Name;
                List <string> foreignKeys        = new List <string>();

                var multiplicity       = GetMultiplicity(nav.ToEndMember.RelationshipMultiplicity);
                var targetMultiplicity = GetMultiplicity(nav.FromEndMember.RelationshipMultiplicity);

                if (multiplicity != NavigationPropertyMultiplicity.Many)
                {
                    foreignKeys.AddRange(nav.GetDependentProperties().Select(p => p.Name));
                }

                navBuilder = entityBuilder.Navigation(nav.Name);

                navBuilder.Nullable           = multiplicity == NavigationPropertyMultiplicity.ZeroOrOne;
                navBuilder.Multiplicity       = multiplicity;
                navBuilder.Target             = new ClrTypeInfo(targetClrType);
                navBuilder.TargetProperty     = targetPropertyName;
                navBuilder.TargetMultiplicity = targetMultiplicity;
                navBuilder.ForeignKey         = foreignKeys;
            }

            return(entityBuilder);
        }
Exemplo n.º 30
0
        public void AutomaticFixupTest()
        {
            var metadataModelBuilder = new MetadataModelBuilder();

            metadataModelBuilder.Entity <ArticleName>().PrimaryKey.AddRange(new[] { "ArticleId", "LanguageId" });
            var articleEntity = metadataModelBuilder.Entity <Article>();

            metadataModelBuilder.Entity <ReceiptDetail>();
            metadataModelBuilder.Entity <Invoice>().BaseEntity = metadataModelBuilder.Entity(typeof(Receipt));
            var contactSettings = metadataModelBuilder.Entity <ContactSettings>();

            articleEntity.HasOne(p => p.ArticleSettings).WithPrincipal();
            contactSettings.HasOne(p => p.Contact).WithDependant();

            metadataModelBuilder.ApplyConventions();

            var invoice = new Invoice {
                Id = Guid.NewGuid()
            };
            var article = new Article {
                Id = Guid.NewGuid(), ArticleNumber = "12314", SupplierId = Guid.NewGuid(), ArticleDescription = "testchen"
            };

            var detail = new ReceiptDetail {
                Id = Guid.NewGuid(), Receipt = invoice, ReceiptId = invoice.Id, Amount = 123, ArticleId = article.Id
            };

            invoice.Details.Add(detail);

            var name1 = new ArticleName {
                ArticleId = article.Id, LanguageId = "de", TranlatedText = "Text 1"
            };
            var name2 = new ArticleName {
                ArticleId = article.Id, LanguageId = "en", TranlatedText = "Text 1"
            };

            var context = new ModelContext(metadataModelBuilder.ToModel());

            context.Attach(new[] { name1, name2 });
            context.AttachSingle(article);

            Assert.Equal(article, name1.Article);
            Assert.Equal(article, name2.Article);
            Assert.Equal(2, article.Names.Count);
            Assert.Contains(article.Names, p => p == name1);
            Assert.Contains(article.Names, p => p == name2);

            context.AttachSingle(invoice);

            Assert.Equal(article, detail.Article);

            Assert.Null(article.ArticleSettings);

            var articleSettings = new ArticleSettings {
                Id = article.Id, Whatever = "test"
            };

            context.AttachSingle(articleSettings);

            Assert.Equal(article.ArticleSettings, articleSettings);
        }