0

这是我要解决的问题的简化版本:

有两个实体:

物品

物品 ID (PK)

其他简单属性...

WorkItem(导航属性)

工作项

物品 ID (PK)

其他简单属性...

项目(导航属性)

 

我需要为它创建一个项目和一个 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。

4

2 回答 2

0

根据您给出的示例,我相信您应该使用继承。WorkItem 实体应继承自 Item 实体。然后,在您的代码中,您只需要使用 WorkItem 实体,它也将具有 Item 实体的所有属性。另外,WorkItem 实体将使用来自 Item 实体的密钥。

于 2012-03-15T12:26:00.680 回答
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 属性是内部声明的;这样序列化器就不会尝试序列化属性并将其发送到服务器。

[AtomIgnore] 是我在 DataServiceContext.WritingEntity 的处理程序中创建并查找的属性。处理程序在将它们发送到服务器之前去除标记有此属性的属性。如果属性是 ref 类型,这种技术似乎不起作用,因此使用 internal.

将其声明为内部也意味着它不能从 XAML 绑定,幸运的是我只需要绑定到几个属性,这样解决方法就很简单了。

于 2012-03-21T11:31:26.520 回答