1

我是 WCF 的新手,今天我遇到了 DataContracts 的问题。当对象从 WCF 服务返回到客户端时出现异常。

SvcTraceViewer 显示下一个异常:

键入 “System.Data.Entity.DynamicProxies.Person_7C797A477DD73534D4E8E743E1FCC1C75DAB75933D03B845A097A8B83F2DD748” 数据合同名称 “Person_7C797A477DD73534D4E8E743E1FCC1C75DAB75933D03B845A097A8B83F2DD748:HTTP://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies” 预计不会。考虑使用 DataContractResolver 或将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表中。

我有几个解决方案。

  • DataAccess(EntityFramework EDMX文件放在这里)
  • 模型(由 DbContextGenerator 生成的实体在这里)
  • WCF 服务(DataContracts 在Model项目中实现)
  • WPF 应用程序(运行 ServiceHost)
  • 控制台应用程序(调用 WCF 项目或 WPF 应用程序中托管的服务)

这是 WCF 中的操作合同:

[OperationContract]
Person[] GetAllPersons(int version);

接口实现:

public Person[] GetAllPersons(int version)
{
    return StorageService.GetAllPersons(version);
}

在客户端(ConsoleApp)接收数据时抛出异常。

我猜这个问题与生成的实体有关,因为它们是部分类

这是 Person 类:

public partial class Person
{
    public Person()
    {
        this.Project = new HashSet<Project>();
    }

    public int Id { get; set; }
    public Nullable<long> AddressId { get; set; }
    public string LastName { get; set; }
    public string MiddleName { get; set; }
    public string FirstName { get; set; }
    public Nullable<long> GeoLocationId { get; set; }
    public string FullGeoLocationName { get; set; }
    public Nullable<long> SupervisorId { get; set; }
    public Nullable<long> PositionId { get; set; }
    public string Position { get; set; }
    public string Office { get; set; }
    public string NativeName { get; set; }
    public string Location { get; set; }
    public string FullName { get; set; }
    public Nullable<long> PmcPersonId { get; set; }

    public virtual ICollection<Project> Project { get; set; }
    public virtual PersonDataVersion DataVersion { get; set; }
    public virtual Workspace Workspace { get; set; }
}

我试图用[DataContract][DataMember]属性标记类及其成员,但仍然发生错误。[KnownType(typeof(Person)]属性也没有帮助。

是否可以将生成的实体用作数据合约?

4

2 回答 2

2

DynamicProxies 表明您正在使用延迟加载,并且该错误可能是由于 WCF 尝试序列化对象时关闭的上下文引起的。

尝试禁用延迟加载并改用急切加载。

于 2012-11-06T19:13:16.787 回答
0

您确实应该将 Person 对象映射到数据传输对象或 Poco 对象。您可以使用 DataMember 属性相应地装饰这些属性。如果您必须禁用延迟加载,您将失去 ORM 的优势,并且将对您甚至可能不使用的数据运行查询 - 在小型系统中可能不是一个大问题,但随着系统的增长,它可能会使它们陷入困境。

于 2012-11-06T19:42:45.870 回答