在使用RIA服务的项目中,我有一个Customer表和一个Address表来存储每个客户的地址。
在silverlight的页面上,我有客户数据,当我展开控件时,会加载该客户的地址数据。
当我用他的地址创建一个新客户时,如何保存这两个客户? Address实体包含CustomerId。这是必填字段。
如果customerId不存在,如何保存地址?我也不能先保存客户,因为它需要地址。
我该怎么办?
答案 0 :(得分:0)
让我澄清一下。仅仅因为实体具有导航属性并不意味着您无法创建它们。你认为你有一个“不能创造一个没有另一个,但不能创造另一个没有那个”的感觉并不是EF的工作方式。
有一种简单的方法可以做到这一点。以下示例使用匿名委托(lambda exression)来首先创建Customer。从服务器返回操作后,delegate / lambda表达式处理已完成的事件,并允许您保存该客户的地址。
此模型假设您在客户和地址之间有1对多的关系... aka:1客户可以拥有多个地址。 Customer的Id字段是Address(CustomerId)中的外键。
private void SaveCustomerAndAddress()
{
CustomerContext context = new CustomerContext();
Customer c = new Customer();
c.Name = "Daniel";
context.Customers.Add(c);
context.SubmitChanges( submitChangesComplited =>
{
//Lambda expressions. Executes when the Completed event fires for the
//SubmitChanges. At this point the Customer entity that was created
//will have its Id assigned by the context, so you can access it
//from within the lambda expression block.
Address address = new Address();
address.CustomerId = c.Id;
address.Name = "Home Address";
address.State = "CA";
address.City = "San Diego";
context.Addresses.Add(address);
context.SubmitChanges();
}, null);
}
但是,如果您在客户和地址之间建立了一种与经济有关的关系,那么您必须更具创造性。操作如下: 1.节省客户 2.保存地址 3.在joiner表中为CustomerAddress关联创建记录。
注意:使用lambda表达式可以使事情变得更容易,因为您可以访问lambda表达式之外的变量,只要它们在同一个方法中声明即可。否则,对于每个操作,如果需要多个操作来实现您想要的操作,则必须将对象保持为“状态”:
答案 1 :(得分:0)
如果您正在使用Entity Framework,并且正确映射了键和外键,那么您不必手动指定键,只需通过导航属性设置它(例如c.address = MyCreatedAddress或a。 customer = MyCreatedCustomer)以及您在上下文中首先保存的实体,这将通过导航保存相应的实体。属性。
你必须记住的一件事是,如果你有1对1的关系而不是1对1的关系,那么映射中的两个表的主键应该是相同的(EF不会让你选择其他AFAIK)
(很老的问题,但有时可能对某人有所帮助:)。