cre*_*mor 5 .net c# entity-framework ef-code-first entity-framework-6
假设我有以下实体类:
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; }
}
Run Code Online (Sandbox Code Playgroud)
这些应该如何在 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);
}
}
Run Code Online (Sandbox Code Playgroud)
在两个类中映射关系的双方。
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);
}
}
Run Code Online (Sandbox Code Playgroud)
映射关系的两侧,但仅在其中一个类中。该代码与选项 2 类似,只是两个构造函数之一为空。
这些选项之间有什么区别吗?如果是,还请解释为什么我应该或不应该使用特定选项。
我会选择选项 3。
在选项 1 中,您可能会忘记映射关联的反向端。在这个简单的示例中,很明显 和Order.Customer是Customer.Orders同一关联的两端。当事情变得更加复杂时,这一点并不总是显而易见的。而且,它是冗余代码。
在选项 2 中,您可能会遇到冲突的映射。例如当你有...
HasOptional(x => x.Customer).WithMany(x => x.Orders);
Run Code Online (Sandbox Code Playgroud)
...在 中OrderMap,您将收到一个运行时异常,告诉您两个映射不匹配。再说一遍,这是多余的代码。
所以选项 3 是干燥且安全的。唯一的问题是在哪里配置映射有点随意。我倾向于坚持在父母的映射中映射孩子。
还有一条评论。您可能想CustomerId在 中添加一个原始属性Order。映射看起来像:
public class CustomerMap : EntityTypeConfiguration<Customer>
{
public CustomerMap()
{
HasMany(x => x.Orders).WithRequired(x => x.Customer)
.HasForeignKey(o => o.CustomerId);
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以完全控制关联的两端以及要使用的外键名称。除此之外,与独立关联(没有原始外键属性)相比,这些外键关联还有一些优点。例如,无需从数据库获取父对象即可建立关联的能力。您只需设置一个 Id 值即可。