Запутался в разделении проблем с ISHession и нетерпеливой загрузкой nHibernate - PullRequest
2 голосов
/ 11 марта 2011

У меня есть приложение, созданное с использованием Fluent NHibernate и ASP.NET MVC. На данный момент он разделен на 5 проектов.

WEB

Проект ASP.NET MVC содержит только HTML, CSS, контроллеры и очень специфичные для проекта валидаторы и связыватели моделей, а также контейнер IoC Ninject

МОДЕЛЬ

Проект Models содержит объекты домена IRepository<T>, Службы, которые используют репозиторий, и вспомогательный код, не связанный с операциями базы данных.

СТОЙКОСТЬ

Проект Persistence содержит отображение Fluent nHibernate, отображение ISessionFactory, реализацию Repository<T> : IRepository<T> и т. Д.

PERSISTENCE.UTILITIES

Это вспомогательный проект, который имеет мало общего с моим фактическим конечным продуктом. Здесь я помещаю такие вещи, как тестирование заполнения базы данных, коллекции по умолчанию для быстрой настройки и т. Д.

TEST

Проект модульных испытаний


Проблема, с которой я сталкиваюсь, находится между Models и Persistence. Есть определенные случаи, когда мне нужно использовать готовая загрузка . В nHibernate я бы использовал Query<T>().Fetch(...) для этого. Это будет работать нормально, за исключением того, что Models.dll не имеет понятия nHibernate. Он не имеет понятия о какой-либо библиотеке, кроме System.dll, и является полностью автономным.

Есть ли какой-нибудь особый способ добавить возможность загружать Eager в мой IRepository без знания NHibernate.Linq? Я не могу добавить метод, который принимает любое лямбда-выражение, которое включает в себя Fetch, потому что мой уровень персистентности не существует на уровне модели. Но IRepository<T> существует на уровне модели, потому что он используется в объектах Service, которые также не имеют понятия о базе данных. Они просто получают доступ к соответствующим репозиториям. Хранилища не доступны для слоя Web, а только для соответствующих сервисов.

Есть идеи?

Ответы [ 3 ]

2 голосов
/ 11 марта 2011

Я думаю, что понимаю вас ... так что все сводится к тому, как вы реализуете шаблон репозитория.Вы можете установить загружаемую загрузку в отображениях с текучей средой, НО независимо от этого, похоже, что вы хотите выполнять загрузочную загрузку только в нескольких случаях, поэтому поэтому материал NHibernate все равно должен проникнуть в ваш проект Model с текущей настройкой.

Возвращаясь ко всему шаблону репозитория, я могу придумать один вариант - сделать ваши репозитории немного умнее.

Например, в вашем проекте Models есть:

public interface IFooRepository : IRepository<Foo>
{
    IQueryable<Foo> GetAllFoosWithBars();
}

Тогда в вашем Persistence проекте есть:

public class FooRepository : Repository<Foo>, IFooRepository
{
    public IQueryable<Foo> GetAllFoosWithBars()
    {
        return this.Session.Query<Foo>().Fetch(c => c.Bars);
        //I don't know the return type for .Fetch() off the top of
        //my head, so you might need a .AsQueryable() in there
    }
}
1 голос
/ 11 марта 2011

Если вы определили свой IRepository как IQueryable, вы можете использовать LINQ на самом хранилище. Например:

public interface IRepository<T> : IQueryable<T>
{
}

public class Repository<T> : IRepository<T>
{
    public Repository(ISession session)
    {
        query = session.Query<T>();
    }

    public Type ElementType
    {
        get { return query.ElementType; }
    }
    public Expression Expression
    {
        get { return query.Expression; }
    }
    public IQueryProvider Provider
    {
        get { return query.Provider; }
    }

    IQueryable<T> query;
}

Тогда вы можете использовать (после ссылки System.Linq):

IRepository<Foo> repo = new Repository<Foo>();
Foo foo = repo.FirstOrDefault(f => f.Bar == "bar");
0 голосов
/ 26 мая 2012

Проблема, с которой я сталкиваюсь, заключается в том, что между моделями существует постоянство. Там Есть определенные моменты, когда мне нужно использовать нетерпеливую загрузку. В nHibernate я будет использовать Query (). Fetch (...), чтобы сделать это. Это будет работать нормально, кроме Models.dll не имеет понятия nHibernate. Не имеет понятия любая библиотека кроме System.dll и является полностью автономной.

Мне кажется, единственная библиотека, которая могла бы извлечь наибольшую выгоду из NH, не использует ее. Только Интернет и Постоянство используют NH, но это Модель, которая использует абстрактную версию NH, скрытую за низкофункциональным IRepository. Я предлагаю вам разрешить NH в Модели и использовать ISession, которая на самом деле является полным полнофункциональным хранилищем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...