我在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。只是有点令人气愤的是:)
如果你对我提出这个问题,我已经欠你谢谢了。如果您了解我的问题并提出任何建议,我将不胜感激。
答案 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
}