假设我有以下实体类:
public class Customer {
public int Id { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Order {
public int Id { get; set; }
public virtual Customer Customer { get; set; }
}
如何将这些映射到Entity Framework 6流畅的代码优先映射?我希望明确地说明映射,而不是依赖于自动映射约定。
只需映射两个类的本地属性。这就是我在Fluent NHibernate中的表现。
public class CustomerMap : EntityTypeConfiguration<Customer> {
public CustomerMap() {
HasMany(x => x.Orders);
}
}
public class OrderMap : EntityTypeConfiguration<Order> {
public OrderMap() {
HasRequired(x => x.Customer);
}
}
在两个班级中映射关系的两侧。
public class CustomerMap : EntityTypeConfiguration<Customer> {
public CustomerMap() {
HasMany(x => x.Orders).WithRequired(x => x.Customer);
}
}
public class OrderMap : EntityTypeConfiguration<Order> {
public OrderMap() {
HasRequired(x => x.Customer).WithMany(x => x.Orders);
}
}
映射关系的两侧,但仅限于其中一个类。代码类似于选项2,两个构造函数中只有一个是空的。
这些选项之间有什么区别吗?如果是,请解释为什么我应该或不应该使用特定选项。
答案 0 :(得分:2)
我会选择选项3 。
在选项1中,您可能忘记映射关联的反向结束。在这个简单的例子中,很清楚Order.Customer
和Customer.Orders
是同一关联的两端。当事情变得更复杂时,这并不总是显而易见的。此外,它是冗余代码。
在选项2中,您可能存在冲突的映射。例如,当你有...时
HasOptional(x => x.Customer).WithMany(x => x.Orders);
...在OrderMap
中,您将收到一个运行时异常,告诉您两个映射都不匹配。而且,这是多余的代码。
因此选项3是干燥且安全的。唯一的问题是它在配置映射的位置有点随意。我倾向于坚持在父母的映射中映射孩子。
还有一条评论。您可能希望在CustomerId
中添加原始属性Order
。映射看起来像:
public class CustomerMap : EntityTypeConfiguration<Customer>
{
public CustomerMap()
{
HasMany(x => x.Orders).WithRequired(x => x.Customer)
.HasForeignKey(o => o.CustomerId);
}
}
现在您可以完全控制关联的两端和要使用的外键名称。除此之外,这些外键关联还有一些优点,而不是独立关联(没有原始外键属性)。例如,无需从数据库中获取父对象即可建立关联。您只需设置一个Id值即可。