2012-04-04 30 views
0

私はエンティティマッピングを既存のデータベースに設定するために、Fluent APIを使用してEnterprise Framework 4.3.1を使用しています。外部キーとしての主キーが重複定義例外をスローする

私は親テーブルの2つの外部キーである主キーを持つ結合テーブルを持つ非常に特殊なケースがあります。

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. 

私のテーブルはこのようなものになるだろう:

私は取得していますエラーがある

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

をそして、これは、特定のエンティティことをセットアップする私のコードです:

//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)); 
} 

私の質問は...私は間違っていますか?私は右のそれを取得する場合、あなたが何をしようとして、次のようなものでなければなりません

答えて

2

... ..

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); 

...キーがHasForeignKeyにIMOで、
希望このヘルプ

注:もちろんは空でもかまいませんが、通常はすべての部分を同様にマップします。

+0

あなた、それは正しいです! Stil、私がよく理解していないことがあります: 'HasForeignKey'は' Map'とどう違うのですか?つまり、モデルからIDのプロパティを取り出してデータベースの列にマップしたいのであれば、元のコードに戻って失敗するでしょう。実質的な違いは何ですか? – Alpha

+0

... '列が '存在しない'のように - 「クラスはFK-sの一時列としてdb内に存在します」 - クラス内のプロパティにそれらの列をマップするのではなく、明確にするためです。 – NSGaga

+0

hehe、ありがとう、私はまだ疑いがあると思う。それでも、もう一度、ソリューションに感謝します。 – Alpha