实体框架,在一个实体被其他几个实体使用时为场景建模

时间:2017-10-04 22:47:09

标签: entity-framework orm entity-framework-6 entity-framework-core

我们有一个模型,其他实体(域)使用公共实体,如果可能的话,我们希望以通用方式在实体之间创建关系。

在示例中,地址由学生和学校使用,每个地址可以有一个或多个地址,一个地址只能属于一个实体(不是很多关系)

 public class Address
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int? RefId { get; set; }
    }

 public class School
    {
        public int Id { get; set; }
        public string SchoolName { get; set; }
        public ICollection<Address> Address { get; set; }
    }

    public class Student
    {
        public int Id { get; set; }
        public string StudentName { get; set; }
        public ICollection<Address> Address { get; set; }
    }

EF6模型首先创建以下模式(没有任何其他配置)

CreateTable(
                "dbo.Addresses",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Name = c.String(),
                        RefId = c.Int(),
                        School_Id = c.Int(),
                        Student_Id = c.Int(),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.Schools", t => t.School_Id)
                .ForeignKey("dbo.Students", t => t.Student_Id)
                .Index(t => t.School_Id)
                .Index(t => t.Student_Id);

基本上,为每个实体添加外键。这个模型有效,但我们不确定这是否是最佳实践。

我们看到的问题是,当使用Address添加其他实体时,我们需要继续添加新实体的ID和FK(例如Library - LibraryId)。它打破了地址概念的抽象。

我们尝试使用抽象引用标识(RefId)并将EF配置为将其用作FK密钥,但它为同一个表创建了两个FK。

另一种选择是不使用任何导航属性并手动填充和处理实体之间的关系 - 实际上不使用ORM功能。

由于这似乎是一种常见的情况,有没有办法以通用方式对其进行建模?

1 个答案:

答案 0 :(得分:0)

一种方法是创建一个抽象类并从中继承:

public abstract class AddressRef
{
    public int AddressId { get; set; }

    // Navigational properties
    public virtual Address { get; set; }
}

现在,您可以在需要地址引用时继承上述类:

public class School : AddressRef
{
    // other properties
}

public class Student : AddressRef
{
    // other properties
}

这将允许您仅在一个地方管理引用,并在您需要的任意数量的类中使用它。