EDM - > POCO - > WCF(.NET4)但是传输集合会导致IsReadOnly设置为TRUE

时间:2010-03-19 17:04:46

标签: wcf entity-framework entity-framework-4 poco

好吧,这可能听起来有些'非正统',但是...使用VS2010和实体框架的新POCO t4模板(Walkthrough: POCO Template for the Entity Framework),我可以生成很好的POCO。然后,我可以在WCF服务中使用这些POCO(作为DTO),主要是从EDM一直到客户端。有点这个人正在做什么(POCO with EF 4.0 and WCF 4.0),除了一切都是自动生成的。我知道实体和DTO'应该'是不同的,但在这种情况下,我正在处理客户端和服务器,并且在模型中使用DTO并自动生成有一些真正的优势。

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

我更愿意做一堆客户端'订单编辑',然后发回更新的订单,而不是进行数十次服务器往返(例如AddProductToOrder(product))。我也不想在Entity和DTO之间进行一堆thunking。总而言之,这对我来说很好......除了只读部分。

是否存在解决方案,或者这对SOA粒度是否太过分了?

2 个答案:

答案 0 :(得分:0)

当反序列化发生时,分配给ICollection的FixupCollection将重新创建为Array。这就是为什么您的产品系列是只读的。

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

但是,如果您使用该选项重用现有程序集中现有的类型并引用包含您的实体的程序集,则前一个选项将不会应用于现有类型,并且您的Products集合中仍会有数组。

我使用的解决方法(仅当您在客户端重用类型并引用实体程序集时)是修改T4模板以检查集合在get of Products中是否为只读,如果是,则设置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;                   
}

答案 1 :(得分:0)

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

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

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

我们已经修改了tt,创建了一个空构造函数来调用基础构造函数,并且这样做了。