3

好的,这听起来可能有点“非正统”,但是……使用 VS2010 和新的 POCO t4 实体框架模板(演练:实体框架的 POCO 模板),我可以生成不错的 POCO。然后,我可以在 WCF 服务中使用这些 POCO(作为 DTO),基本上从 EDM 一直到客户端。这家伙在做什么(带有 EF 4.0 和 WCF 4.0 的 POCO),除了一切都是自动生成的。我知道实体和 DTO“应该”是不同的,但在这种情况下,我正在处理客户端和服务器,并且在模型中自动生成 DTO 有一些真正的优势。

我的问题是,当我传输具有关系的实体时,客户端生成的集合(ICollection)具有只读值集,因此我无法操纵该关系。例如,检索现有订单时,我无法将产品添加到 Products 集合客户端...... Products 集合是只读的。

我宁愿做一堆客户端“订单编辑”,然后发回更新的订单,而不是进行数十次服务器往返(例如 AddProductToOrder(product))。我也不想在 Entity 和 DTO 之间进行大量的转换。所以总而言之,这对我来说看起来不错……除了只读部分。

有没有解决方案,或者这对 SOA 颗粒来说太过分了?

4

2 回答 2

0

“la mouette”解决方案适用于引用的程序集:

我们也有同样的问题,我们注意到属性 IsReadOnly 在 wcf 序列化后设置为 true(之前,属性值为 false)。

我们已经引用了程序集。在“la mouette”提出的解决方法中,使用参数化构造函数,但我们的 POCO 模板没有。

我们已经修改了 tt 创建一个空的构造函数来调用基础构造函数,这样就可以了。

于 2010-09-14T16:24:32.067 回答
0

当反序列化发生时,分配给您的 ICollection 的 FixupCollection 将重新创建为数组。这就是为什么您的 Products 集合是只读的。

为了修改它,您可以使用“添加服务引用”中的选项(至少在 VS2010 上存在),将 Collection 类型更改为其他类型(Generic.List 或 Generic.Observable)。

但是,如果您使用选项来重用现有程序集中存在的类型并引用包含您的实体的程序集,则先前的选项将不会应用于现有类型,并且您的 Products 集合中仍然有 Array。

我使用的一种解决方法(仅当您在客户端重用类型并引用您的实体程序集时)是修改 T4 模板以检查集合是否在产品的获取中是只读的,如果是,则设置一个 FixupCollection:

if (<#=code.FieldName(navProperty)#>.IsReadOnly)
{
    var newCollection = new FixupCollection<<#=code.Escape(navProperty.ToEndMember.GetEntityType())#>>(<#=code.FieldName(navProperty)#>);
    newCollection.CollectionChanged += Fixup<#=navProperty.Name#>;
    <#=code.FieldName(navProperty)#> = newCollection;                   
}
于 2010-08-25T16:12:29.487 回答