2009-10-07 2 views
5

Я новичок в NHibernate (и ORMS) и пытаюсь справиться с множеством различных вариантов, которые он представляет. Для справки я использую Fluent NHibernate с отдельными бизнес-объектами, которые, в свою очередь, используют DTO исключительно для доступа к данным. Моя архитектура приложений должна поддерживать как окна, так и веб-интерфейсы.Лучший подход для построения NHibernate DTO's

Мое quandry является одним из общих подходов, поскольку, похоже, существует так много вариантов. Мой DTO выглядит примерно так, как показано ниже. Каждый DTO имеет ссылку на ISession, который передается им из BO. Они несут ответственность за их собственную нагрузку и сохранить:

public class EmployeeDTO... 

    // Data Properties to be persisted to the database 
    public virtual int Id { get; private set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 
    public virtual ISession Session { get; set; } 

    // Save logic 
    public virtual void Save() 
    { 
     var transaction = Session.BeginTransaction(); 
     Session.SaveOrUpdate(this); 
     transaction.Commit(); 
    } 

    // Load logic 
    public virtual void Load(int id)... 

Прежде всего: Является ли это правильный подход принять - если DTO имеет возможность сохранять и загружать себя?

Во-вторых: Независимо от того, где сохранить/код нагрузки лежит, вы должны использовать один и тот же ISession для жизни или объекта, или они должны иметь реф к ISessionFactory и открыть новый сеанс все взаимодействия с базой данных времени необходимо?

// Open a new session every time I interact with the repository 
    var session = FluentSupport.SessionFactory.OpenSession(); 
    var transaction = Session.BeginTransaction(); 
    Session.SaveOrUpdate(this); 
    transaction.Commit(); 
    session.Close(); 
    // Close the session when I'm done 

Конечно всегда есть вариант 3, ни один из выше :)

+0

Когда объект знает, как сохранить себя, называется DAO, это не имеет никакого отношения к DTO –

ответ

10

В общем, DTOS не содержит поведение (например, Save, Load) и не содержат знания о том, как они получают сохранялись (ISession). Похоже, что вы действительно создаете слой данных. Идеальный бизнес-уровень также не должен знать об ISession. Тем не менее, вы можете сократить это расслоение, все, что вам нужно, поскольку оно соответствует вашим потребностям, но, вероятно, будет сложно перейти на другую ORM позже, если ваш ORM будет проходить через все ваши слои.

Для управления жизненным циклом ISession вам необходимо решить, собираетесь ли вы использовать шаблон UnitOfWork, который в основном говорит, что каждый запрос пользователя получает новый ISession. Существуют и другие варианты срока службы ISession, и вы действительно не ограничены в этом отношении. Часто могут быть лучшие методы работы с веб-приложениями и приложениями Windows по сравнению с любыми другими типами приложений, но вы не указали, что вы пишете.

+0

. Architecure должен поддерживать как web (Silverlight), так и окна (WPF). – Steve

+0

. Я уточнил этот вопрос, чтобы его охватить. .. – Steve

2

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

В вашем сценарии я бы, вероятно, пошел на сервисный подход, чтобы хранить данные извлечения. что означает, что DTO будет использоваться только внутри границ службы. Если вам нужно скопировать объекты, которые выглядят одинаково, я предлагаю вам взглянуть на AutoMapper, который был создан для этой конкретной цели. Если у вас есть только окна или только веб-проект, это не проблема. Это когда ты смешиваешься. Вы не можете обрабатывать сеансы одинаково в приложении Windows, как в веб-приложении.

9

Сохраните свой код для загрузки/сохранения отдельно от ваших DTO. Объектами DTO являются только просмотров основных данных.

Выполняя свои запросы, возвращайте DTO с помощью преобразования. Что-то вроде этого:

resultSet = session.CreateCriteria(typeof(MyDataObject)) 
    .Add(query criteria, etc.) 
    .SetResultTransformer(Transformers.AliasToBean<MyDTOObject>()) 
    .List<IMyDTOObject>()
+0

Какие критерии я могу использовать в методе Add (привязать свойство домена к свойству DTO)? –

+0

@SilvioDelgado: Извините, я не работал с NHibernate более 3 лет, поэтому не знаю. –

+0

Нет проблем. В любом случае, спасибо. :) –

3

DTO предназначены для «объектов передачи данных». То есть, немые объекты, используемые для передачи значений или наборов значений в вашей системе. Они не должны нести ответственность за сохранение себя или даже сопоставление 1-1 с объектами домена в вашем доменном слое.

Смежные вопросы