【问题标题】:RIA Services: Entities Parent Child relationshipRIA 服务:实体父子关系
【发布时间】:2011-02-19 08:46:21
【问题描述】:
在使用 RIA 服务的项目中,我有一个 Customer 表和一个 Address 表来存储每个客户的地址。
在 silverlight 的页面上,我有客户数据,当我展开控件时,会加载该客户的地址数据。
当我用他的地址创建一个新客户时,我如何分别保存这两个? Address 实体包含 CustomerId。这是必填字段。
customerId 不存在时如何保存地址?而且我也不能先保存客户,因为它需要地址。
我能做什么?
【问题讨论】:
标签:
silverlight
entity-framework
ria
【解决方案1】:
让我澄清一些事情。仅仅因为实体具有导航属性并不意味着您不能创建它们。你认为你有一个 22 条“没有另一个就不能创造一个,但没有一个就不能创造另一个”的看法并不完全是 EF 的工作原理。
有一种简单的方法可以做到这一点。以下示例首先使用匿名委托(lambda 表达式)创建客户。从服务器返回操作后,委托/lambda 表达式将处理完成的事件并允许您保存该客户的地址。
此模型假设您在客户和地址之间有一对多的关系...也就是: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. 在连接器表中为 CustomerAddress 关联创建记录。
注意:使用 lambda 表达式会使事情变得更容易一些,因为您可以访问 lambda 表达式之外的变量,只要它们在同一方法中声明即可。否则,对于每个操作,如果需要多个操作来实现您想要的,您必须将对象持久化到“状态”中:
【解决方案2】:
如果您使用的是实体框架,并且正确映射了键和外键,那么您不必手动指定键,只需通过导航属性(例如 c.address = MyCreatedAddress 或 a. customer = MyCreatedCustomer) 以及您在上下文中首先保存的任何实体,这将通过导航保存相应的实体。属性。
您必须记住的一件事是,如果您有 1 对 1 的关系而不是 1 对多的关系,那么映射中两个表的主键应该相同(EF 不会让您有其他选择阿法克)
(很老的问题,但有时可能会对某人有所帮助:)