这是我要解决的问题的简化版本:
有两个实体:
ItemID(PK)
其他简单的属性......
WorkItem(导航属性)
ItemID(PK)
其他简单属性......
项目(导航属性)
我需要为它创建一个Item,一个WorkItem,我需要设置两个导航属性,以便两个实体在保存之前可以互相指向。
我可以这样做:
Item newItem = Item.CreateItem(0, blah,blah,blah);
service.AddToItems(newItem);
WorkItem newWorkItem = new WorkItem();
service.AddToWorkItems(newWorkItem);
//set the navigation properties
newItem.WorkItem = newWorkItem;
newWorkItem.Item = newItem;
不幸的是,当涉及到保存时,这会失败。我相信EF在尝试设置WorkItem的Item关联时会尝试设置WorkItem的主键。
有人可以告诉我正确的方法吗?
更新:
所以,我尝试使用继承来构建模型。该模型建立并验证。
不幸的是,为我的模型添加WCF数据服务并尝试在浏览器中查看服务给了我:
..... <m:message xml:lang="en-US">An error occurred while processing this request. </m:message>
<m:innererror>
<m:message>Navigation Properties are not supported on derived entity types. Entity Set 'app_Items' has a instance of type 'tempmodel.app_CostItem', which is an derived entity type and has navigation properties. Please remove all the navigation properties from type 'tempmodel.app_CostItem'.</m:message>
<m:type>System.InvalidOperationException</m:type>
<m:stacktrace> at System.Data.Services.Serializers.SyndicationSerializer.WriteObjectProperties(IExpandedResult expanded, ......
CostItem是另一个实体,如WorkItem,它派生自Item。
答案 0 :(得分:0)
根据您提供的示例,我相信您应该使用继承。 WorkItem实体应该从Item实体继承。然后,在您的代码中,您只需要使用WorkItem实体,它也将具有Item实体的所有属性。另外,WorkItem实体将使用Item实体中的键。
答案 1 :(得分:0)
我在每个客户端部分“子”类中创建了一个虚拟属性:
private Item _BaseItem;
[AtomIgnore]
internal Item BaseItem
{
get
{
if (_BaseItem != null)
return _BaseItem;
else
return this.Item;
}
set
{
_BaseItem = value;
OnPropertyChanged("Item");
}
}
客户端上的代码使用此BaseItem属性反向遍历对象图。所以建立关系的代码现在看起来像这样:
Item newItem = Item.CreateItem(0, blah,blah,blah);
service.AddToItems(newItem);
WorkItem newWorkItem = new WorkItem();
service.AddToWorkItems(newWorkItem);
//set the navigation properties
newItem.WorkItem = newWorkItem;
newWorkItem.**BaseItem** = newItem;
注意,BaseItem属性被声明为internal;这是因为序列化程序不会尝试序列化属性并将其发送到服务器。
[AtomIgnore]是我创建的属性,在我的DataServiceContext.WritingEntity处理程序中查找。处理程序在将属性标记为发送到服务器之前将其删除。如果属性是ref类型,这种技术似乎不起作用,因此使用内部。
将其声明为内部也意味着它无法从XAML绑定,幸运的是我只需要绑定到几个属性,这样就可以直接解决问题。