Linq to Sql:分离/重新附加实体以通过线路发送

时间:2011-04-28 14:22:02

标签: .net linq-to-sql serialization n-tier-architecture

我在N-Tier环境中使用L2S,并且在尝试通过线路发送关联实体时遇到问题。我提前为这个冗长的问题道歉,但这是一个非常具体的情况。

基本上我正在加载一个表,称之为Items,另一个表,称之为ItemMappings。 Items和ItemsMappings在一对多关系中相关。因此每个ItemMapping都有一个ItemId属性。在L2S中,我在Item类中获得了ItemMappings的集合,在ItemMappings类中获得了Item引用,这很棒。

但是,由于N-Tier环境,我设计了一些封装类来封装客户端的更改跟踪,以便在返回服务器进行保存时可以检索它。这通过跟踪每个实体类型的更改来工作。这意味着我有一个物品跟踪集(TrackingSet

所以这意味着我通过电线分别发送Items和ItemMappings(实际上它们是在一个容器中一起发送的,但就序列化而言,它们是分开的)。现在,如果我不介入序列化过程,那么物品集合的实际内容就像下面的伪XML一样:

<items>
  <item>
    <itemId>1</itemId>
    <itemMappings> 
      <itemMapping>
        <itemId>1</itemId>
      </itemMapping>
    </itemMappings>
  </item>
  <item>
    <itemId>2</itemId>
    <itemMappings> 
      <itemMapping>
        <itemId>2</itemId>
      </itemMapping>
    </itemMappings>
  </item>
</items>

我想要展示的是序列化物品集合包括与物品相关联的物品映射。但是因为项目映射实际上也是被发送的,所以实际上我最终发送了两次项目映射集合:一次独立,并且一旦嵌入到items集合中。这意味着我的线路占用空间不必要地大。

我想要做的是在容器类的OnSerializing方法中分离实体,只在itemMapping对象上保留项ID,然后在OnDeserialized方法中,根据这些ID重新关联它们。

不幸的是,在OnSerializing方法中,如果我将ItemMapping.Item属性设置为null,然后尝试将ItemID属性设置为我刚设置为null的Item的ID,则会得到臭名昭着的ForeignKeyReferenceAlreadyHasValueException。只是有点令人气愤的是:)

如果你对我提出这个问题,我已经欠你谢谢了。如果您了解我的问题并提出任何建议,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

在序列化期间修改实例的属性肯定是一个麻烦的方法!

我建议使用一些用于查询数据库的类,以及其他用于线表示的类。这会使您的数据库与服务合同分离。

public class ServiceResponse
{
  public List<Item> TheItems {get;set;}
  public List<ItemMapping> TheMappings {get;set;}
}

public class Item
{
  public int ItemId {get;set;}
  // TODO more properties, but no ItemMappings property
}

public class ItemMapping
{
  public int ItemId {get;set;}
  // TODO more properties
}