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); }
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))); }); }
public void DefaultStructureConventionTest() { var builder = new MetadataModelBuilder(); builder.Entity <Invoice>(); builder.Entity <Article>().HasOne(p => p.ArticleSettings).WithPrincipal(); builder.ApplyConventions(); TestModelValidations.ValidateInvoiceArticleDefaultModel(builder); }
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); }
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()); }
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))); } } }
public void MetadataModelBuilderGenericEntityTest() { var builder = new MetadataModelBuilder(); var entityBuilder = builder.Entity <Receipt>(); Assert.Equal("Receipt", entityBuilder.Name); Assert.Equal(typeof(Receipt), entityBuilder.TypeInfo.ClrType); }
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); }
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)); }
public void MetadataModelBuilderMaxLengthTest() { var builder = new MetadataModelBuilder(); var entityBuilder = builder.Entity <Receipt>(); builder.ApplyConventions(); Assert.Equal(100, entityBuilder.Property(c => c.ReceiptNumber).MaxLength); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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"); }
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); }
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); } }
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); }
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); } }
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); }
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); }