Лучший подход к созданию NHibernate DTO - PullRequest
5 голосов
/ 07 октября 2009

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

Мой вопрос - один из общих подходов, так как кажется, что вариантов так много. Мой 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 иметь возможность сохранять и загружать себя?

Во-вторых: Независимо от того, где находится код сохранения / загрузки, следует ли вам использовать одну и ту же сессию IS для жизненного цикла или объекта или они должны иметь ссылку на 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, ничего из вышеперечисленного:)

Ответы [ 4 ]

10 голосов
/ 07 октября 2009

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

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

9 голосов
/ 07 октября 2009

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

При выполнении запросов возвращайте DTO с помощью преобразования. Как то так:

resultSet = session.CreateCriteria(typeof(MyDataObject))
    .Add(query criteria, etc.)
    .SetResultTransformer(Transformers.AliasToBean<MyDTOObject>())
    .List<IMyDTOObject>()
3 голосов
/ 07 октября 2009

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

2 голосов
/ 07 октября 2009

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

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

...