How to map child entity to parent entity without introducing primitive type parent linker in child entity?
Solution 1
I don't understand why do you use fluent mapping? Your model should be mapped by default conventions. If you want to map it with fluent mapping use:
modelBuilder.Entity<Product>()
.HasMany(x => x.ProductPriceList) // Product has many ProductPricings
.WithRequired(y => y.Product) // ProductPricing has required Product
.Map(m => m.MapKey("ProductId")); // Map FK in database to ProductId column
Solution 2
This has the correct answer:
I almost got it:
modelBuilder.Entity<ProductPricing>()
.HasRequired(x => x.Product)
.WithMany()
.Map(x => x.MapKey("ProductId"));
I just forgot to put the principal's dependent(i.e. ProductPriceList. I hope I'm getting the right terminology, wanted to stay away from parent child terminology ^_^):
modelBuilder.Entity<ProductPricing>()
.HasRequired(x => x.Product)
.WithMany(x => x.ProductPriceList)
.Map(x => x.MapKey("ProductId"));
Entity Framework's Fluent Mapping is hardly fluent, there's some stutter you could unwittingly commit if you are not very familiar with each method's nuances :-) Lookie that, I almost got it correct. Passing both ProductPricing
and ProductPriceList
look redundant, hardly intuitive.
EF's fluent mapping is hardly a good fluent(of which intuitiveness should be an innate quality) interface citizen, isn't it?
Hao
Updated on June 22, 2022Comments
-
Hao almost 2 years
I have these classes:
public class Product { [Key] public virtual int ProductId { get; set; } public virtual string ProductName { get; set; } public virtual string Category { get; set; } public virtual IList<ProductPricing> ProductPriceList { get; set; } [Timestamp] public virtual byte[] Version { get; set; } } public class ProductPricing { // no ProductId here public virtual Product Product { get; set; } [Key] public virtual int ProductPricingId { get; set; } public virtual DateTime EffectiveDate { get; set; } public virtual decimal Price { get; set; } }
This is my modelBuilder:
modelBuilder.Entity<Product>(). HasMany(x => x.ProductPriceList) .WithRequired() .HasForeignKey(x => x.Product);
This is the error:
The foreign key component 'Product' is not a declared property on type 'ProductPricing'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.
UPDATE
I've tried the following, corresponding errors below the code
modelBuilder.Entity<Product>() .HasMany(x => x.ProductPriceList) .WithRequired();
{"Invalid column name 'Product_ProductId1'.\r\nInvalid column name 'Product_ProductId'.\r\nInvalid column name 'Product_ProductId1'."}
modelBuilder.Entity<Product>() .HasMany(x => x.ProductPriceList) .WithRequired() .Map(x => x.MapKey("ProductId"));
{"Invalid column name 'Product_ProductId'."}
modelBuilder.Entity<Product>() .HasMany(x => x.ProductPriceList) .WithRequired(x => x.Product);
{"Invalid column name 'Product_ProductId'.\r\nInvalid column name 'Product_ProductId'."}
modelBuilder.Entity<Product>() .HasMany(x => x.ProductPriceList) .WithRequired(x => x.Product) .Map(x => x.MapKey("ProductId"));
{"Multiplicity constraint violated. The role 'Product_ProductPriceList_Source' of the relationship 'TestEfCrud.Mappers.Product_ProductPriceList' has multiplicity 1 or 0..1."}
If it could help, here's the DDL:
create table Product ( ProductId int not null identity(1,1) primary key, ProductName varchar(100) not null, Category varchar(100) not null, Version rowversion not null ); create table ProductPricing ( ProductId int not null references Product(ProductId), ProductPricingId int identity(1,1) not null primary key, EffectiveDate datetime not null, Price decimal(18,6) not null );
UPDATE 2
I've tried this answer, which looks a bit similar to my case, mapping originated from child entity How to map parent column in EF 4.1 code first
However, using this:
modelBuilder.Entity<ProductPricing>() .HasOptional(x => x.Product) .WithMany() .Map(x => x.MapKey("ForeignKeyColumn"));
and this:
modelBuilder.Entity<ProductPricing>() .HasRequired(x => x.Product) .WithMany() .HasForeignKey(x => x.Product);
Both resulted to this error:
{"Invalid column name 'Product_ProductId1'.\r\nInvalid column name 'Product_ProductId1'.\r\nInvalid column name 'Product_ProductId1'."}