EF6与旧版SQL数据库中有2个表的一对多关系

时间:2019-01-14 21:52:45

标签: .net entity-framework-6 poco ef-fluent-api

我正在尝试配置一对多关系,其中第二个表引用了第一个表。这些表位于现有的旧版SQL Server数据库中。

我有一个Customer表和一个CustomerBranches表,如下所示:

enter image description here

我有一个POCO,如果有对象,它可以使Customer对象导航到其BranchCustomers(子级),如果本身是Child,也可以导航到其ParentCustomer(父级)。

public class Customer
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<Customer> BranchCustomers { get; set; }
    public virtual Customer ParentCustomer { get; set; }
}

我无法使用它来处理数据注释或Fluent API。

我可以在EF中获得与工作“排序”的关系的唯一方法是使用Fluent API使用多对多关系:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{    
        modelBuilder.Entity<Customer>()
            .HasMany<Customer>(s => s.BranchCustomers)
            .WithRequired(c => c.ParentCustomers)
            .Map(cs =>
            {
                cs.MapLeftKey("ParentCustId");
                cs.MapRightKey("ChildCustId");
                cs.ToTable("CustomerBranches");
            });

    }

和POCO:

public class Customer
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<Customer> BranchCustomers { get; set; }
    public virtual List<Customer> ParentCustomers { get; set; }
}

在这种情况下,当客户是孩子时,ParentCustomers集合将只有一位客户。我知道这太过分了。在这种情况下合适的方法是什么?

谢谢。

2 个答案:

答案 0 :(得分:1)

ORM不是对象数据库。 ORM就是它-只是一个映射工具。将表映射到类,将FK映射到引用。

但是您可以将自己的“工具”属性添加到实体。为什么不呢?

  override def onClientError(request: RequestHeader,
                             statusCode: Int,
                             message: String): Future[Result] = {
    logger.debug(
      s"onClientError: statusCode = $statusCode, uri = ${request.uri}, message = $message")

}

当然,这会增加抽象泄漏的数量。

答案 1 :(得分:0)

如果我做对了,看来您正在理论上尝试实现composite模式(的一部分)。但是您的表结构具有误导性。因此,最好的选择是首先重组POCO类。因为拥有这个额外的表没有任何额外的优势(或者我错过了什么吗?)。

您可能只有一个独特的“客户”表,并有一个额外的列引用了它的ParentCustomerID。然后,当Customer位于最上方且没有父级时,它将ParentCustomerID设置为null。

因此,您的POCO类应如下所示:

public abstract class AbstractCustomer{
   [Key]
   public int Id { get; set; }
   public string Name { get; set; }

   public Guid? ParentCustomerID { get; set; }
   public virtual Customer ParentCustomer { get; set; }
}

public class Customer : AbstractCustomer
{        
    public virtual List<AbstractCustomer> BranchCustomers { get; set; }   
}

请注意?运算符,并且父类必须是抽象的。 然后,使用流畅的API,EF配置将如下所示:

modelBuilder.Entity<AbstractCustomer>().ToTable("Customer").HasOptional(a => a.ParentCustomer).WithMany(s => s.BranchCustomers).HasForeignKey(fk => fk.ParentCustomerID);

希望它能帮助您愉快地编写代码!