сериализация wcf и ленивая загрузка nhibernate - PullRequest
2 голосов
/ 19 апреля 2009

Я использую .net 2.0 с NHibernate / ActiveRecord и WCF.

До сих пор я не использовал загрузку NH Lazy, но потери производительности слишком велики, чтобы их игнорировать, поэтому я начинаю использовать ее.

Из того, что я читал до сих пор, это непростая тема, использующая сущности NH с отложенной загрузкой и сериализацией в WCF, но преимущества слишком велики, чтобы их игнорировать.

Используя код, который я нашел здесь: Сериализация WCF С NHibernate я смог заставить WCF распознавать основные типы.

Я также создаю DataContractSerializer следующим образом:

public override XmlObjectSerializer CreateSerializer(Type standard, XmlDictionaryString name, XmlDictionaryString NS, IList<Type> knownTypes)
{
    return new DataContractSerializer(standard, name, NS, knownTypes, 0x989680, false, true /* Preserve References*/, new HibernateDataContractSurrogate());
}

Моя проблема, когда у меня что-то вроде этого:

[DataContract, ActiveRecord("POS_POSCUSTOMERS",Lazy = true)]
public class POSCustomer : ActiveRecordForPOS<POSCustomer>
{
    private Branch belongsToBranch;

    [DataMember,BelongsTo("BRANCH")]
    public virtual Branch BelongsToBranch
    {
        get { return belongsToBranch; }
        set { belongsToBranch = value; }
    }
}

и

[DataContract, ActiveRecord("BRANCHES",Lazy = true)]
public class Branch : ActiveRecordForPOS<Branch>
{
    private POSCustomer defaultPOSCustomer;

    [DataMember, BelongsTo("POS_POSCUSTNUM", Cascade= CascadeEnum.None)]
    public virtual POSCustomer DefaultPOSCustomer
    {
        get { return defaultPOSCustomer; }
        set { defaultPOSCustomer = value; }
    }
}

Branch.DefaultPOSCustomer и POSCustomer.BelongsToBranch - это две несвязанные сущности, но это одни и те же сущности, например Branch 200 имеет DefaultPOSCustomer 100, а POSCustomer имеет BelongsToBranch 200.

Проблема в том, что, когда WCF пытается сериализовать граф объектов, он переходит между DefaultPOSCustomer и BelongsToBranch, как будто не распознает, что это одни и те же сущности и что он уже сериализовал их, пока не столкнется с переполнением стека. .

Если я отключу Lazy = true для этих классов, сериализация будет работать нормально.

  1. Как DataContractSerializer решает, что объект уже сериализован?
  2. Как я могу остановить это поведение?
  3. Возможно, есть какой-нибудь другой способ сериализации отложенной загрузки сущностей с помощью WCF?

p.s. Я рассматривал другое решение - создать нечто похожее на NHibernate Proxy, но заменить свойства, относящиеся к другим классам, на необработанный ключ, поэтому вместо свойства типа Branch у меня будет свойство типа int. со значением 200. Таким образом, я мог бы избежать проблемы с циклом, с которой столкнулся, но я бы попробовал это как последнее средство, так как его было бы довольно сложно поддерживать.

edit: у меня много сущностей, поэтому о создании dto для каждой из них не может быть и речи, и создать его динамически было бы сложно, поэтому я бы предпочел этого избегать или использовать в качестве крайней меры. Мне также нужно заниматься бизнес-логикой на стороне сервера, поэтому мне понадобятся не сущности, а сущности.

редактировать: ну, не повезло, если вы идете прямым путем NH / AR / WCF. Я пойду с созданием DTO, который кажется более простым.

Ответы [ 3 ]

2 голосов
/ 13 сентября 2009

Я только что заметил, что не закрыл свой вопрос, я пошел с DTO-решением, и оно пока работает просто отлично.

0 голосов
/ 19 января 2011

Мы использовали это решение и обнаружили, что оно проще / лучше, чем решение DTO.

0 голосов
/ 11 сентября 2009

Уже слишком поздно, чтобы ответить ;-) Но в любом случае это происходит потому, что лениво загруженные объекты являются прокси-классами NH; и кажется, что они разные, когда загружены, как это. Одним из решений является переопределение .Equals () для сравнения свойства Id для постоянных сущностей. Я думаю, у вашей сущности есть что-то вроде первичного ключа. Это, вероятно, сделает WCF счастливым, только если он использует равенство, а не сравнение ссылок. Если WCF всегда использует ReferenceEquals - не повезло.

...