Циклические ссылки с использованием объектов POCO и сервисов Silverlight - PullRequest
0 голосов
/ 29 февраля 2012

Я создал несколько объектов POCO, которые имеют отношения между ними. Например, сущность «Individual» имеет отношение OneToMany с сущностью «Collection». Вот как я их определил:

[DataContract(IsReference=true)]
[KnownType(typeof(User))]
[KnownType(typeof(Address))]
[KnownType(typeof(Collection))]
[KnownType(typeof(Donation))]
[KnownType(typeof(CollectorRating))]
[KnownType(typeof(DonatorRating))]
[Table("Individuals")]
public class Individual : User
{
    // ... Lots of attributes

    [DataMember]
    [InverseProperty("Collector")]
    public virtual ICollection<Collection> Collections { get; set; }

    // Lots of other attributes
}

А сущность Коллекции:

[DataContract(IsReference=true)]
[KnownType(typeof(Individual))]
[KnownType(typeof(Organization))]
[KnownType(typeof(Donation))]
[KnownType(typeof(DeliveryDay))]
[KnownType(typeof(Address))]
[Table("Collections")]
public class Collection
{
    // Other attributes

    [DataMember]
    [InverseProperty("Collections")]
    public virtual Individual Collector { get; set; }

    // ... Attributes
}

Мой сервис является Silverlight-совместимым сервисом, который определяется следующим образом:

[ServiceContract(Namespace = "")]
[SilverlightFaultBehavior]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class IndividualService
{
    [OperationContract]
    public User GetByEmail(string email)
    {
        using (var context = new EntitiesContext())
        {
            Individual user = context.Individuals.SingleOrDefault(u => u.Email == email);

            return user;
        }
    }
}

Это работает, как и ожидалось: я получаю отдельный объект, который заполнен членами данных, и пустой массив коллекций.

Однако, как только я попытаюсь включить отношения:

context.Individuals.Include("Collections").SingleOrDefault(u => u.Email == email)

У меня есть исключение переполнения стека, что довольно раздражает. Я почти уверен, что это циклическая ошибка ссылки, однако я попробовал все решения (добавив IsReference = true к атрибуту DataContract ...). Единственное, что работает, это замена атрибута DataMember атрибутом IgnoreDataMember в сущности Collection, однако я теряю двунаправленное отношение, это то, что я хочу для этого конкретного объекта ...

1 Ответ

0 голосов
/ 29 февраля 2012

Избегайте n-уровневой рекурсии в ваших контрактах данных, так как у вас будут проблемы с десериализацией их (может произойти переполнение стека).Подумайте о выравнивании вашей структуры DTO.Вы можете смоделировать отношения между родителями и детьми без рекурсии.

В качестве альтернативы попытайтесь определить максимальный уровень рекурсии, который требуется поддерживать, и смоделируйте его явно в структуре DTO.

...