与传统SQL数据库中的2个表的EF6一对多关系

问题描述 投票:3回答:2

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

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

enter image description here

我有一个POCO,它允许Customer对象导航到它的BranchCustomers(Children),如果有的话,还可以导航到它的ParentCustomer(Parent),如果它是一个Child。

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; }
}

在这种情况下,当Customer是孩子时,ParentCustomers集合将只有一个客户。我知道这是一块垃圾。在这种情况下,适当的方法是什么?

谢谢。

.net entity-framework-6 poco ef-fluent-api
2个回答
1
投票

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

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

 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; }
    public Customer ParentCustomer { 
           get{
              return BranchCustomers.FirstOrDefault(); 
           }
    }
    public void SetParent(var p) { 
              return BranchCustomers.Add(p);
    }
}

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


0
投票

如果我做对了,看起来你正试图在理论上实现(部分)composite模式。但是你的表结构是误导性的。因此,最好的选择是首先重新组织POCO类。因为这个额外的桌子没有额外的好处(或者我错过了什么?)。

您可以拥有一个唯一的Customers表,其中一个额外的列引用其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);

希望它有帮助和快乐的编码!

© www.soinside.com 2019 - 2024. All rights reserved.