EF6(代码优先)单个外键属性上的多个导航属性

Posted

技术标签:

【中文标题】EF6(代码优先)单个外键属性上的多个导航属性【英文标题】:EF6 (code first) Multiple nav properties on single foreign key property 【发布时间】:2017-12-07 23:05:35 【问题描述】:

在将我的数据层从 Telerik 迁移到 EF6 时,我遇到了 POCO 命名问题EF 模型是从现有数据库生成的“代码优先”。因为我不想更改业务层,所以所有迁移/配置都需要在数据层中完成。我还尝试保持数据库中的EF 代码生成不变,以便将来维护,同时使用部分类来保持遗留代码的完整性。

所以EF 生成带有FK 引用的poco,如下所示:

public partial class MyPoco

        public Guid? MyForeignKeyDatabasePocoId  get; set;  /* Foreign key database column */

        public virtual MyForeignKeyDatabasePoco  get; set;  /* Navigation property MyForeignKeyDatabasePocoId database column */

这是开箱即用的,因为命名约定是正确的(生成的) 但是现在我喜欢添加一个基于同数据库FK Id(业务层使用)的导航属性,

public partial class MyPoco


        [ForeignKey("MyForeignKeyApplicationPoco", "MyForeignKeyDatabasePocoId")]  /* <- not possible, no constructor accepts two parms */
        public Guid? MyForeignKeyDatabasePocoId  get; set;    /* Foreign key database column */

        public virtual MyForeignKeyDatabasePoco get; set;     /* Navigation property FK MyForeignKeyDatabasePocoId database column */

        public virtual MyForeignKeyApplicationPoco get; set;  /* Navigation property FK MyForeignKeyDatabasePocoId database column */

我尝试使用 [ForeignKey("MyForeignKeyApplicationPoco")] 装饰 Id 属性,但随后它抱怨“MyForeignKeyDatabasePoco”没有(外)键。我也不能为 id 属性设置两个外键装饰器。

MyForeignKeyDatabasePoco 和 MyForeignKeyApplicationPoco 是相似的,它们都存在于模型中。

A) 这可能吗? B)当实体 MyPoco 被定义(或 fk poco 的一个或两个)时,我是否应该在 OnModelCreating(DbModelBuilder modelBuilder) 中更改某些内容? C)我是否应该摆脱生成的导航属性以支持遗留业务属性(不是首选选项)

任何帮助将不胜感激。

在 bubi 发表评论后编辑

通过继承解决了它。首先抽象出数据库poco,然后应用程序poco继承自数据库poco

public abstract partial class MyForeignKeyDatabasePoco 

    /* EF generated code */ 


public partial class MyForeignKeyApplicationPoco : MyForeignKeyDatabasePoco 

    /* additional things todo */ 


public partial class MyPoco

        public Guid? MyForeignKeyDatabasePocoId  get; set;  /* Foreign key database column */

        public virtual MyForeignKeyApplicationPoco  get; set;  /* Navigation property to MyForeignKeyDatabasePocoId database column */

在流式模型中添加了 DbSet,并在流式中添加了 OnModelCreating(DbModelBuilder modelBuilder) modelBuilder.Entity();

【问题讨论】:

【参考方案1】:

其实我认为如果不添加带有外键字段名称的属性,是不可能使用属性的。在这种情况下,您可以使用 ForeignKey 属性将属性设置为外键。

否则你可以使用流畅的配置(通常我使用这种方式)。

modelBuilder.Entity<OfficeAssignment>() 
        .HasRequired(t => t.PianoDiRientro)
        .WithMany(t => t.Rates)
        .Map(d => d.MapKey("IdPianoDiRientro"));

在这种情况下是一对多关系(一个PianoDiRientro多个Rates),外键列名称是IdPianoDiRientro

【讨论】:

我认为你是对的。不可能有属性。我已经使用继承解决了它。使 database-poco 抽象,application-poco 继承 database-poco。不是我理想的解决方案,但它似乎有效。

以上是关于EF6(代码优先)单个外键属性上的多个导航属性的主要内容,如果未能解决你的问题,请参考以下文章

EF 6 代码首先,在导航属性上使用包含更改外键 ID 会导致“发生引用完整性约束违规”错误

EF代码中视图之间的导航属性优先

EF6:代码优先复杂类型

没有导航属性的EF Code First外键

同一主键上的EF多个外键关系

使用 EF 6.0 和代码优先的一对一 EntityTypeConfiguration