Primary key as foreign key throws duplicate definition exception

Go To StackoverFlow.com

0

I'm using Enterprise Framework 4.3.1 with its Fluent API to set up my entities mapping to an existing database.

I have a very special case with a associative table which has it's primary key to be, at the same time, two foreign keys of their parent tables.

The error I'm getting is:

Schema specified is not valid. Errors: 
(68,6) : error 0019: Each property name in a type must be unique. Property name 'ProductId' was already defined.
(69,6) : error 0019: Each property name in a type must be unique. Property name 'PropertyId' was already defined.

My tables would be something like this:

Products (ProductId, ...)
ProductProperties (ProductPropertyId, ...) // does not depend on Product!
DefaultPropertyValues (ProductId (FK1, PK), ProductPropertyId (FK2, PK), DefaultValue)

And this is my code that sets up that specific entity:

//table mapping
modelBuilder.Entity<DefaultPropertyValue>().ToTable("DefaultPropertyValues", "dbo");

//not null value
modelBuilder.Entity<DefaultPropertyValue>().Property(d => d.DefaultValue).IsRequired();
//primary key
modelBuilder.Entity<DefaultPropertyValue>().HasKey(d => new { d.ProductId, d.ProductPropertyId });

//foreign key 1 -- see helper method
SetupGenericOneToManyForeignKey<DefaultPropertyValue, Product>(modelBuilder, d => d.Product, "ProductId");
//foreing key 2 -- see helper method
SetupGenericOneToManyForeignKey<DefaultPropertyValue, ProductProperty>(modelBuilder, d => d.ProductProperty, "ProductPropertyId");

//helper method
private CascadableNavigationPropertyConfiguration SetupGenericOneToManyForeignKey<TDependent, TParent>(DbModelBuilder modelBuilder, Expression<Func<TDependent, TParent>> foreignKeyField, string dbForeignKeyField) where TDependent: class where TParent: class
{
    return modelBuilder.Entity<TDependent>().HasRequired<TParent>(foreignKeyField).WithMany().Map((m) => m.MapKey(dbForeignKeyField));
}

So, my question is... what am I doing wrong?

2012-04-04 20:15
by Alpha


2

...if I get it right, what you're trying to do, should be something like this..

public class Product
{
    public int ProductId { get; set; }
    public virtual ICollection<DefaultPropertyValue> DefaultPropertyValues { get; set; }
}
public class ProductProperty 
{
    public int ProductPropertyId { get; set; }
    public virtual ICollection<DefaultPropertyValue> DefaultPropertyValues { get; set; }
}
public class DefaultPropertyValue 
{
    public int ProductId { get; set; }
    public int ProductPropertyId { get; set; }
    public Product Product { get; set; }
    public ProductProperty ProductProperty { get; set; }
}
...
modelBuilder.Entity<DefaultPropertyValue>()
    .HasKey(i => new { i.ProductId, i.ProductPropertyId });

modelBuilder.Entity<DefaultPropertyValue>()
    .HasRequired(i => i.Product)
    .WithMany(u => u.DefaultPropertyValues)
    .HasForeignKey(i => i.ProductId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<DefaultPropertyValue>()
    .HasRequired(i => i.ProductProperty)
    .WithMany(u => u.DefaultPropertyValues)
    .HasForeignKey(i => i.ProductPropertyId)
    .WillCascadeOnDelete(false);

...the key is IMO in the HasForeignKey,
hope this helps

NOTE: WillCascadeOnDelete is optional of course and WithMany could be empty but I usually map all parts similarly.

2012-04-04 21:53
by NSGaga
You, sir, have it right! Stil, there's something I don't quite understand: how is it that HasForeignKey is so different than Map? I mean, what if I wanted to take out my ids properties from the model, and map it to the database columns, I would go back to my original code and it would fail. What's the substantial difference - Alpha 2012-04-04 23:57
...columns that do not 'exist' - as in 'they exist just in the db as temp columns for FK-s' - as opposed to having those columns mapped to properties in the class - just to clarify - NSGaga 2012-04-05 00:13
hehe, thanks, I think we'll still have the doubt. Still, again, thanks a lot for the solution - Alpha 2012-04-05 00:16
learn to live with it :) - EF is near perfect state right now, was much much worse - btw. you can upvote too! : - NSGaga 2012-04-05 00:18
Ads