主键作为外键引发重复定义异常
本文关键字:异常 定义 | 更新日期: 2023-09-27 18:30:06
我使用带有Fluent API的Enterprise Framework 4.3.1来设置映射到现有数据库的实体。
我有一个非常特殊的情况,关联表的主键同时是其父表的两个外键。
我得到的错误是:
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));
}
所以,我的问题是…我做错了什么?
。。。如果我做对了,你想做的应该是这样的。。
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,
希望这能帮助
注意:WillCascadeOnDelete
当然是可选的,WithMany
可以是空的,但我通常会类似地映射所有部分。