我在EF 4.1中迈出了第一步。因为我使用的是NHibenate,所以代码第一种方法在我看来是最好的方法。我对一对多(或多对一)实现的良好映射存在问题。假设我有两个实体:
class ClientModel
{
int ClientID;
string Name;
virtual IList<OrderModel> Orders;
}
class OrderModel
{
int OrderID;
string Details;
virtual ClienModel Client;
}
当我这样离开时,生成数据库时出错 - 表中的键丢失。我想通过将键的名称更改为ID(但是我的命名约定不合适)或添加[Key]注释,我可以解决它。即使我添加了这个注释,表格的名称仍然是错误的 - 就像类名,但是带有's'。 所以我尝试使用流畅的API - 我制作了映射。但是,如果我像这里一样设置映射:
class ClientMapping
{
ClientMapping()
{
this.HasKey(e => e.ClientID).Property(e => e.ID).HasColumnName("ClientID");
this.Property(e => e.Name).HasColumnName("Name");
this.HasMany(e => e.Orders).WithOptional().Map(p => p.MapKey("OrderID")).WillCascadeOnDelete();
this.ToTable("Clients");
}
}
class OrderMapping
{
OrderMapping()
{
this.HasKey(e => e.OrderID).Property(e => e.OrderID).HasColumnName("OrderID");
this.Property(e => e.Details).HasColumnName("Details");
this.HasRequired(e => e.Client).WithMany().Map(p=>p.MapKey("Client")).WillCascadeOnDelete(false);
this.ToTable("Orders");
}
}
数据库中表之间的关系加倍。 使用代码优先方法进行一对多关系的正确方法是什么?我是在朝着一个好方向思考,还是一个错误的方法?
修改
好的,我已经以 @Eranga 显示的方式完成了,但仍然存在问题。当我从数据库获取Client时,其Orders属性为null(但在数据库中,它有一些Order.ClientID == Client.ClientID的订单)。
答案 0 :(得分:6)
您需要映射参与该关系的两个属性。您需要将ClientID
列添加到订单表。
class ClientMapping
{
ClientMapping()
{
this.HasKey(e => e.ClientID).Property(e => e.ID).HasColumnName("ClientID");
this.Property(e => e.Name).HasColumnName("Name");
this.HasMany(e => e.Orders).WithRequired(o => o.Client)
.Map(p => p.MapKey("ClientID")).WillCascadeOnDelete();
this.ToTable("Clients");
}
}
class OrderMapping
{
OrderMapping()
{
this.HasKey(e => e.OrderID).Property(e => e.OrderID).HasColumnName("OrderID");
this.Property(e => e.Details).HasColumnName("Details");
this.ToTable("Orders");
}
}
从一个实体配置关系就足够了。
答案 1 :(得分:0)
这可能有所帮助(当我无法弄清楚它是如何工作时,它帮助了我):
如果你有这样的课程:
class ClientModel
{
int ClientId;
string Name;
}
class OrderModel
{
int OrderId;
string Details;
int ClientId;
}
然后这将代表数据库中的2个表,这些表“不会”通过外键相互连接(它们将通过ClientId
中的OrderModel
连接)你可以从数据库中获取“GetAllOrdersWithSomeClientId”和“GetTheClientNameForSomeClientId”等数据。但是当您从数据库中删除Client
时会出现问题。因为那时仍然会有一些Orders
包含ClientId
,Client
表中不再存在virtual List<OrderModel> Orders;
,这会导致数据库出现异常。
需要ClientModel
(在virtual ClienModel Client;
)和OrderModel
(在ClientModel
中)来创建关系aka。表OrderModel
和int ClientId;
之间的外键。
有一件事我还不确定。哪个是OrderModel
中的ClientId
。我想它必须与ClientModel
中的this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
具有相同的名称,以便实体框架知道外键必须连接哪两个属性。如果有人能够详细解释这一点,那就太好了。
另外,如果某些东西不起作用,请将它放入DbContext构造函数中:
{{1}}