Дженерики с Fluent и NHibernate

Я пытаюсь создать систему обмена сообщениями между пользователями и организациями, то есть пользователь может отправлять и получать сообщения от пользователей или организаций.

Итак, для поддержки этой системы я начал с интерфейса:

public interface IPassableObject<F, T, O>
    where F : DomainObject 
    where T : DomainObject
{
    Guid PassedItemId { get; set; }
    O Item { get; set; }
    F From { get; set; }
    T To { get; set; }
    DateTime Created { get; set; }
}

Идея в том, что позже я хотел бы иметь возможность передавать больше, чем просто сообщения - например, сериализованные объекты. Итак, у нас есть класс с 3 универсальными типами. Кому, откуда и объект

Затем я создал свой класс сообщений

public class Message<T, F> : DomainObject, IPassableObject<T, F, string>
    where F : DomainObject
    where T : DomainObject
{

    public Message()
    {
        Created = DateTime.Now;
    }

    #region IPassableObject<T,F> Members

    public virtual Guid PassedItemId { get; set; }

    public virtual string Item { get; set; }

    public virtual T From { get; set; }

    public virtual F To { get; set; }

    public virtual DateTime Created { get; set; }

    #endregion
}

Затем я сделал свою таблицу для поддержки моих переданных элементов:

CREATE TABLE dbo.PassedItems
(
    PassedItemId            uniqueidentifier        NOT NULL,
    FromId                  uniqueidentifier        NOT NULL,
    ToId                    uniqueidentifier        NOT NULL,
    SerializedObject        varchar(max)            NOT NULL,
    Created                 datetime                DEFAULT(GETEDATE()) NOT NULL,

    CONSTRAINT PK_PassedItems PRIMARY KEY CLUSTERED (PassedItemId)
)

Идентификаторы как для моих пользователей, так и для организаций являются гидами. Теперь у меня есть свободное сопоставление для сообщений «Пользователь — Пользователь». Я думаю, что мне нужно будет создать только 4 сопоставления, а не поддерживать 4 отдельных класса для пользователей-пользователей, пользователей-организаций, организаций-пользователей и организаций-организаций. Я надеялся, что Nhibernate возьмет guid из таблицы и автоматически попытается извлечь объект на основе указанного типа.

public class UserToUserMessageMap : ClassMap<Message<UserProfile, UserProfile>>
{
    public UserToUserMessageMap()
    {
        WithTable("PassedItems");

        Id(x => x.PassedItemId, "PassedItemId").GeneratedBy.Guid();

        Map(x => x.Item, "SerializedObject");
        Map(x => x.Created);

        References(x => x.From, "FromId");
        References(x => x.To, "ToId");
    }
}

Проблема, которую я вижу, заключается в том, что когда я запускаю свое приложение, я получаю ошибку времени выполнения:

NHibernate.MappingException: ассоциация из таблицы PassedItems не указывает ссылочный объект

Итак, будет ли этот подход вообще работать? Что я делаю неправильно? Спасибо!


person Josh    schedule 19.08.2009    source источник
comment
Я попытался изменить ссылки, указав тип. К сожалению, это тоже не сработало: References‹UserProfile›(x =› x.From, FromId);   -  person Josh    schedule 20.08.2009
comment
К сведению: мы используем FluentNHibernate версии 0.1.0.363 и NHibernate версии 2.0.1.4000.   -  person Josh    schedule 20.08.2009


Ответы (2)


Так как же выглядит сопоставление «Откуда» и «Кому»?

Потому что я думаю, что NH не знает, как сопоставить эти объекты, потому что вы не предоставили информацию о сопоставлении.

В общем, мне кажется, что вы заново изобретаете колесо, смотрели ли вы на технологические стеки, такие как веб-сервисы (SOAP и REST), очередь сообщений, удаленное взаимодействие (.Net). И конкретные реализации, такие как WCF, ASMX (веб-сервисы), nServiceBus, MassTransit, MSMQ, и это лишь некоторые из них...

Олли

person AwkwardCoder    schedule 20.08.2009
comment
From и To в этом экземпляре являются объектами UserProfile, которые сопоставлены и работают в течение некоторого времени. Я думаю, вы неправильно понимаете. Сообщение в данном случае не является транспортным протоколом. Это настоящая система обмена сообщениями, в которой пользователи получают сообщения в папку «Входящие», и в конечном итоге я хочу иметь возможность расширить систему, чтобы пользователи и организации могли отправлять больше, чем просто текст. - person Josh; 20.08.2009

Я нашел решение своей проблемы. Чтобы дать грубый обзор того, что я сделал:

Пришлось отказаться от дженериков.

У меня есть свой интерфейс, IPassable.

У меня есть абстрактный класс, который реализует IPassable: PassableBase

У меня есть "фиктивный" класс PassableItem, унаследованный от PassableBase. Этот класс ничего не делает, кроме значений по умолчанию, установленных в PassableBase.

Message — это класс, который также наследуется от PassableBase. Другие переданные объекты должны будут наследовать от PassableBase.

Мое отображение Fluent использует PassableItem.

Мои репозитории используют PassableBase для входных параметров, и я создаю новый PassableItem или получаю PassableItem из хранилища (в зависимости от того, создан он уже или нет), а затем сохраняю/удаляю объект PassableItem.

person Josh    schedule 04.09.2009