停止WCF将空IColse反序列化为零容量数组

时间:2012-04-20 10:58:48

标签: wcf serialization entity-framework-4.1

我在使用WCF和Entity Framework 4.1 POCO对象时遇到问题(使用T4模板生成)。我的基本问题是,当从客户端向服务发送POCO对象时,WCF将ICollection类型的成员变量反序列化为固定大小的数组。

在客户端,我可以告诉visual studio使用IList而不是T [] - 但我在服务器端看不到这样的选项。

这会导致几个问题无法解决,例如将这些对象持久化回数据库。

有没有办法告诉WCF将ICollection(或任何数组)反序列化的对象类型是什么?

2 个答案:

答案 0 :(得分:5)

我很惊讶更多的人没有遇到过这个问题,因为当你试图在WCF上使用EF T4生成的POCO对象时,你会遇到这个问题。具体来说,我得到的错误就是:

  

异常:“无法在实体类型Datalayer.Customers上设置字段/属性订单。有关详细信息,请参阅InnerException。”

     

InnerException:“无法将项目添加到'Datalayer.Order []'类型的固定大小数组中。”

无论如何,我能够提出的唯一解决方案是你提到的解决方案,即修改T4模板以使用HashSet而不是ICollection。不会让我觉得最干净,但似乎有效。

答案 1 :(得分:1)

我使用的是Entity Framework 6,我可以通过在T4模板中进行以下更改来解决此问题。

我更改了以下行,在该行中创建导航属性以使用List而不是

中的集合
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,

navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("List<" + endType + ">") : endType,

然后我更改了在构造函数中设置navigation属性的代码,通过添加对.ToList()的调用将默认的hashset转换为列表。这一行

this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();

已更改为

this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>().ToList();

HashSet&lt;&gt; .ToList()方法是一个扩展,因此为了使该扩展方法可用,我通过修改UsingDirectives方法添加了一个使用System.Linq语句:

    public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
    return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
        ? string.Format(
            CultureInfo.InvariantCulture,
            "{0}using System;{1}" + Environment.NewLine +
            "{0}using System.Linq;" + 
            "{2}",
            inHeader ? Environment.NewLine : "",
            includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
            inHeader ? "" : Environment.NewLine,
            Environment.NewLine)
        : "";
}