WCF - Entity framework, ошибка сериализации сгенерированных сущностей

Я новичок в 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 (здесь находится EDMX-файл EntityFramework)
  • Модель (сущности, созданные DbContextGenerator, находятся здесь)
  • WCF Service (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)] тоже не помог.

Можно ли использовать сгенерированные сущности в качестве контрактов данных?


person opewix    schedule 06.11.2012    source источник


Ответы (2)


DynamicProxies указывают, что вы используете отложенную загрузку, и ошибка может быть вызвана закрытием контекста, когда WCF пытается сериализовать объект.

Попробуйте отключить ленивую загрузку и используйте вместо нее активную загрузку.

person Martin4ndersen    schedule 06.11.2012
comment
Отключение LazyLoading не помогло, но отключение прокси-серверов прошло успешно con.Configuration.ProxyCreationEnabled = false; Спасибо - person opewix; 07.11.2012

Вы действительно должны сопоставить объекты Person с объектами передачи данных или объектами Poco. Вы можете соответствующим образом украсить эти свойства атрибутами DataMember. Если вы должны отключить ленивую загрузку, вы потеряете преимущества ORM, и будут выполняться запросы для данных, которые вы, возможно, даже не используете - это может быть не большой проблемой для небольшой системы, но по мере роста систем это может поставить их на колени.

person TheITGuy    schedule 06.11.2012