【问题标题】:Relationship mapping table with additional properties?具有附加属性的关系映射表?
【发布时间】:2012-05-13 16:22:19
【问题描述】:

我有三个班级:

public partial class Student : Contact
{   
    //Inherited from Contact:
    //public int ContactId { get; set; }
    //public string FirstName { get; set; }
    //public string LastName { get; set; }

    public virtual StudentExam StudentExam { get; set; }
}

public partial class Exam
{
    public int ExamId { get; set; }
    public string Title { get; set; }
    public DateTime Date { get; set; }

    public virtual StudentExam StudentExam { get; set; }
}

public partial class StudentExam
{
    public byte Score { get; set; }
    public int ContactId { get; set; }
    public int ExamId { get; set; }

    public virtual Student Student { get; set; }
    public virtual Exam Exam { get; set; }
}

当尝试初始化 DbContext 时,它会抛出 ModelValidationException: 在模型生成过程中检测到一个或多个验证错误: \tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'StudentExam' 没有定义键。定义此 EntityType 的键。 \tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'StudentExams' 基于没有定义键的类型'StudentExam'。

我尝试将StudentExam 类的属性更改为以下内容:

[Key, ForeignKey("Student"), Column(Order = 0)]
public int ContactId { get; set; }
[Key, ForeignKey("Exam"), Column(Order = 1)]
public int ExamId { get; set; }

现在我得到了这个异常:

\tSystem.Data.Entity.Edm.EdmAssociationEnd: : 多重性在关系“StudentExam_Student”中的角色“StudentExam_Student_Source”中无效。因为从属角色属性不是关键属性,所以从属角色的多重性的上限必须是“*”。 \tSystem.Data.Entity.Edm.EdmAssociationEnd: : 多重性在关系“StudentExam_Exam”中的角色“StudentExam_Exam_Source”中无效。因为从属角色属性不是关键属性,所以从属角色的多重性的上限必须是'*'。

有什么方法可以通过数据注释实现这一点(当我可以使用数据注释时,我不喜欢使用流畅的 API;流畅的 API 会导致代码混乱。

【问题讨论】:

    标签: entity-framework entity-framework-4.1 ef-code-first code-first entity-relationship


    【解决方案1】:

    这不是关于数据注释或流利的 api,而是关于错误定义的类——在你的类中定义的关系根本无法映射,因为它们在关系级别无效。你必须修改你的类:

    public partial class Student : Contact
    {   
        public virtual ICollection<StudentExam> StudentExams { get; set; }
    }
    
    public partial class Exam
    {
        ...
    
        public virtual ICollection<StudentExam> StudentExams { get; set; }
    }
    

    一旦你定义了这个关系,你就可以使用你的数据注释来定义StudentExam类中的键,它会起作用。

    顺便说一句。流利的 api 不会导致代码混乱。凌乱的代码是由程序员而不是 API 创建的。数据标注反过来又违反了 POCO 原则。

    【讨论】:

    • 我保持我的 POCO 干净,稍后我会向其中添加元数据。添加元数据的好处也是独立验证(这也可以用fluent实现吗?)。无论如何,我所说的混乱代码是指所有流畅的代码都进入一个OnModelCreated 方法,而不是每个单独的实体(通过实现这种方法或其他方法)。我正在处理生成的实体,所以它们无论如何都不是真正的开放边缘 POCO(它使用构造函数来初始化导航属性,因此不能在部分类中编写 ctor。我添加了一个 OnCreated 部分方法并调用 gen.entity。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    相关资源
    最近更新 更多