我正在尝试配置一对多关系,其中第二个表具有对第一个表的引用。这些表位于现有的旧版Sql Server数据库中。
我有一个Customer表和一个CustomerBranches表,如下所示:
我有一个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集合将只有一个客户。我知道这是一块垃圾。在这种情况下,适当的方法是什么?
谢谢。
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);
}
}
当然,这增加了抽象泄漏的数量。
如果我做对了,看起来你正试图在理论上实现(部分)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);
希望它有帮助和快乐的编码!