如何使用 EF Code First Fluient API 从主表配置多个外键引用到同一个表
Posted
技术标签:
【中文标题】如何使用 EF Code First Fluient API 从主表配置多个外键引用到同一个表【英文标题】:How to configure multiple Foreignkey referancing to same table from main table using EF Code First Fluient API 【发布时间】:2011-07-12 05:59:41 【问题描述】:我必须使用现有的桌面应用程序数据库设计一个 Web 应用程序。根据现有数据库,我有以下类
public class Company
#region Primitive Properties
public virtual int CompanyID get; set;
public virtual string CompanyName get; set;
public virtual bool IsCustomer get; set;
public virtual string CustomerCode get; set;
public virtual bool IsPotentialCustomer get; set;
public virtual bool IsSupplier get; set;
public virtual string SupplierCode get; set;
public virtual bool IsPotentialSupplier get; set;
public CompanyCategoryCodes CustomerCategoryCode get; set;
public CompanyCategoryCodes SupplierCategoryCode get; set;
public CountryCode CountryCode get; set;
public class CompanyCategoryCodes
public virtual int CategoryID get; set;
public virtual string CategoryCodes get; set;
public virtual bool PotentialCustomer get; set;
public virtual bool PotentialSupplier get; set;
public virtual System.DateTime LastModifiedDate get; set;
public virtual bool Manufacturer get; set;
public class CountryCode
public virtual int CountryCodeID get; set;
public virtual string Code get; set;
public virtual string Description get; set;
public virtual bool DefaultCode get; set;
public virtual bool EECVATApplies get; set;
public virtual System.DateTime LastModifiedDate get; set;
public virtual bool FixedAddressFormat get; set;
EF 代码第一个默认框架是创建名为“CustomerCategoryCode_CategoryID”、“SupplierCategoryCode_CategoryID”、“CountryCode_CountryCodeID”的外键。我希望这个外键名称与我的旧数据库表一致,例如“客户类别代码 ID”、“供应商类别代码 ID”、“国家代码 ID”。我如何使用 EF Code First Fluient API 来做到这一点。我尝试使用 Fluient API 映射来执行此操作,但出现“SupplierCategoryCode_CategoryCodeID”错误,因为“CustomerCategoryCode_CategoryID”也位于同一张表“CompanyCategoryCode”。另外,如果有任何使用数据注释的选项,那么也请告诉我如何实现这一点。
【问题讨论】:
【参考方案1】:您必须手动重新映射每个导航属性以定义其键。比如:
modelBuilder.Entity<Company>()
.HasRequired(c => c.CountryCode)
.WithMany()
.HasForeignKey("CountryCodeID");
modelBuilder.Entity<Company>()
.HasMany(c => c.CustomerCategoryCode)
.WithOptional()
.HasForeignKey("CustomerCategoryCodeID")
.WillCascadeOnDelete(false);
modelBuilder.Entity<Company>()
.HasMany(c => c.SupplierCategoryCode)
.WithOptional()
.HasForeignKey("SupplierCategoryCodeID")
.WillCascadeOnDelete(false);
除非您在每个依赖实体中定义导航属性和外键属性,否则无法使用数据注释:
public class Company
...
[ForeignKey("CountryCode")]
public virtual int CountryCodeID get; set;
public CountryCode CountryCode get; set;
【讨论】:
错误消息是“在表 'Company' 上引入 FOREIGN KEY 约束 'CountryCode_Companies' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建约束。查看以前的错误。" 我们是否需要对 ON DELETE NO ACTION 或 ON UPDATE NO ACTION 做任何事情?仅当我尝试在一个表(公司)中有 2 个 ForiegnKeys(CustomerCategoryCodeID,SupplierCategoryCodeID)尝试引用同一个表(CompanyCategoryCode)时才会发生这种情况 是的,最后两个映射中的至少一个必须以.WillCascadeOnDelete(false)
结尾,因为理论上 SupplierCategoryCodeID
和 CustomerCategoryCodeID
都可以指向导致多个级联路径的同一记录 - 这是不允许的SQL 服务器。
你说得对,我也尝试了同样的方法,现在工作正常,但我还需要添加 Public ICollection在你的上下文类中,你需要重写 OnModelCreating 并映射键,它应该看起来像这样:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Entity<Company>()
.HasRequired(c => c.CustomerCategoryCode)
.WithMany()
.Map(mc => mc.MapKey("CustomerCategoryCodeID"));
【讨论】:
它可能在 OnModelCreating 中工作,但我使用了单独的 Mapping 类,当我尝试将“CustomerCategoryCodeID”和“SupplieCategoryCodeID”指向同一张表“CompanyCategoryCode”时它给了我错误 错误是什么?除了 MapKey 之外,您是否将参数更新为 HasRequired?听起来您可能忘记在复制时将 c.CustomerCategoryCode 更新为 c.SupplierCategoryCode。只是猜测...... 错误消息是“在表 'Company' 上引入 FOREIGN KEY 约束 'CountryCode_Companies' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建约束。查看以前的错误。"以上是关于如何使用 EF Code First Fluient API 从主表配置多个外键引用到同一个表的主要内容,如果未能解决你的问题,请参考以下文章
使用 EF4 Code First 时如何控制生成的 nvarchar 列的长度?