这篇文章讨论多对多的关系。
让我们从最简单的例子开始。我们让 EF4.1 来推断表的映射。我在订单和雇员之间建模多对多的关系。
public
class
Order
{
public int OrderID { get ; set ; }
[Required]
[StringLength( 32 , MinimumLength = 2 )]
public string OrderTitle { get ; set ; }
[Required]
[StringLength( 64 , MinimumLength = 5 )]
public string CustomerName { get ; set ; }
public DateTime TransactionDate { get ; set ; }
public byte [] TimeStamp { get ; set ; }
public virtual List < OrderDetail > OrderDetails { get ; set ; }
public virtual List < Employee > InvolvedEmployees { get ; set ; }
}
public class Employee
{
public int EmployeeID { get ; set ; }
public string EmployeeName { get ; set ; }
public virtual List < Order > Orders { get ; set ; }
}
{
public int OrderID { get ; set ; }
[Required]
[StringLength( 32 , MinimumLength = 2 )]
public string OrderTitle { get ; set ; }
[Required]
[StringLength( 64 , MinimumLength = 5 )]
public string CustomerName { get ; set ; }
public DateTime TransactionDate { get ; set ; }
public byte [] TimeStamp { get ; set ; }
public virtual List < OrderDetail > OrderDetails { get ; set ; }
public virtual List < Employee > InvolvedEmployees { get ; set ; }
}
public class Employee
{
public int EmployeeID { get ; set ; }
public string EmployeeName { get ; set ; }
public virtual List < Order > Orders { get ; set ; }
}
我简单地在订单表中加入一个雇员的列表,在雇员表中加入了一个订单的列表。瞧,这是映射到的表。
现在,我们要控制两件事:
- 关联表的名字
- 在关联表中的两个列名
通过下面的代码可以实现:
modelBuilder.Entity
<
Employee
>
()
.HasMany(e => e.Orders)
.WithMany(e => e.InvolvedEmployees)
.Map(m =>
{
m.ToTable( " EmployeeOrder " );
m.MapLeftKey( " EmployeeID " );
m.MapRightKey( " OrderID " );
});
.HasMany(e => e.Orders)
.WithMany(e => e.InvolvedEmployees)
.Map(m =>
{
m.ToTable( " EmployeeOrder " );
m.MapLeftKey( " EmployeeID " );
m.MapRightKey( " OrderID " );
});
基本上,我们说一个雇员管理多个订单,每个订单涉及多个雇员,因此,我们有了多对多的关系。我们的关联表名为 EmployeeOrder ,左键 (从雇员的角度看,是雇员键) 名为 employee-id,右键名为 order-id。
这样,你可以控制没有直接映射到类的表。
就使用这种模型而言,则是非常简单和自然。
private
static
void
ManyToMany()
{
using (var context = new MyDomainContext())
{
var order = new Order
{
OrderTitle = " Pens " ,
CustomerName = " Mcdo’s " ,
TransactionDate = DateTime.Now,
InvolvedEmployees = new List < Employee > ()
};
var employee1 = new Employee { EmployeeName = " Joe " , Orders = new List < Order > () };
var employee2 = new Employee { EmployeeName = " Black " , Orders = new List < Order > () };
context.Orders.Add(order);
order.InvolvedEmployees.Add(employee1);
order.InvolvedEmployees.Add(employee2);
context.SaveChanges();
}
{
using (var context = new MyDomainContext())
{
var order = new Order
{
OrderTitle = " Pens " ,
CustomerName = " Mcdo’s " ,
TransactionDate = DateTime.Now,
InvolvedEmployees = new List < Employee > ()
};
var employee1 = new Employee { EmployeeName = " Joe " , Orders = new List < Order > () };
var employee2 = new Employee { EmployeeName = " Black " , Orders = new List < Order > () };
context.Orders.Add(order);
order.InvolvedEmployees.Add(employee1);
order.InvolvedEmployees.Add(employee2);
context.SaveChanges();
}
在这个例子中,我甚至都没有在数据上下文中将雇员加入到雇员的集合中,因为他们被引用到订单的集合中,EF 帮我们完成了。