我是EF的新手,我刚刚开始了一个新项目。我目前有一个模型BrandManagers
,其中包含一个主键和三个外键。我不明白我应该如何在DbContext
中映射这些内容。
public class BrandManager
{
public int BrandManagerId { get; set; }
[Required()]
public int PersonId { get; set; }
[Required()]
public int BrandId { get; set; }
[Required()]
public int CountryId { get; set; }
public virtual Person Person { get; set; }
public virtual Brand Brand { get; set; }
public virtual Country Country { get; set; }
}
我将如何映射?我试过以下,但没有用。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.HasRequired(x => x.Country);
modelBuilder.Entity<Brand>()
.HasMany(x => x.BrandManagers);
modelBuilder.Entity<BrandManager>()
.HasRequired(x => x.Person);
modelBuilder.Entity<BrandManager>()
.HasRequired(x => x.Brand);
modelBuilder.Entity<BrandManager>()
.HasRequired(x => x.Country);
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
我一直在
在表'Person'上引入FOREIGN KEY约束'FK_Person_Country_CountryId'可能会导致循环或多个级联路径。
我在ASP.NET网站的介绍教程中没有找到任何解决这个问题的方法,也没有关于此问题的任何问题,所以我开始觉得我误解了一些重要的部分EF。
答案 0 :(得分:2)
我的答案更具体地说明了如何在EF Code First中映射外键。当Lenalent回答并且是正确的时候,我正准备关于多个级联路径的第二部分。所以,不要丢弃我的答案,这可能对你有所帮助,这里是一般如何在EF :)中映射外键的答案。稍微介绍一下底部的级联删除。
您可以使用数据注释,而无需在模型构建器中进行映射。但是,如果您不希望POCO对象标记有数据库注释,我还使用modelBuilder提供了解决方案。
另外请注意,只要您拥有Person引用,就不需要拥有PersonId。在这种情况下,生成器会为您创建FK(并且您的POCO类将不具有它不需要的Id)。但是,使用Id进行延迟加载可能是更好的做法(我不确定这是否是你这样做的原因)。
最后,如果遵循惯例,您甚至不需要设置外键。因此,如果您的国家/地区类的PK为Id,那么当您使用CountryId创建Country引用时,EF将通过命名表明CountryId是国家/地区引用的FK。 (Source)
数据注释:
public class BrandManager
{
public int BrandManagerId { get; set; }
[Required()]
public int PersonId { get; set; }
[Required()]
public int BrandId { get; set; }
[Required()]
public int CountryId { get; set; }
[ForeignKey("PersonId")]
public virtual Person Person { get; set; }
[ForeignKey("BrandId")]
public virtual Brand Brand { get; set; }
[ForeignKey("CountryId")]
public virtual Country Country { get; set; }
}
DbContext :(另外,在这种情况下,您不应该在POCO类上需要任何数据注释,因为它们都是在模型构建器中设置的)
modelBuilder.Entity<BrandManager>()
.HasRequired(x => x.Person)
.WithMany(x=>x.People)
.HasForeignKey(x=>x.PersonId);
至于你得到的具体错误,你需要添加.WillCascadeOnDelete(false)作为指向BrandManager-&gt; Country的宽容。您可以为Person-&gt; Country删除它,但最好删除BrandManager,因为它最终会通过Person路径级联。
答案 1 :(得分:1)
您遇到的问题是SqlServer问题。对于外键关系以及来自级联删除的多个删除路径,它往往非常保守。
你是从品牌经理和人的国家关系中得到的。删除国家/地区将产生两条到品牌经理的路径:
Country -> Person -> Brand Manager
Country -> Brand Manager
解决方案是删除其中一个实体的删除级联:
// Remove the cascade for country->Brand Manager.
// Let it cascade through Person instead
modelBuilder.Entity<BrandManager>()
.HasRequired(x => x.Country)
.WillCascadeOnDelete(false);