Я использую общий репозиторий, который предоставляет IQueryable
следующим образом:
public IQueryable<T> AllEntities
{
get
{
return session.Query<T>();
}
}
Я могу запросить вот так:
var results =
(from e in repository.AllEntities
where e.SomeProperty == "some value"
select e).ToList();
Однако, если T
имеет родительскую и прародительскую сущность, и я хочу загрузить их с нетерпением, я должен сделать это:
var results =
(from e in repository.AllEntities
where e.SomeProperty == "some value"
select e)
.Fetch(x => x.Parent)
.ThenFetch(x => x.Grandparent)
.ToList();
Это работает, но .Fetch
и .ThenFetch
оба являются специальными методами расширения Linq2Nhibernate, что вызывает две проблемы:
Я должен включить с использованием NHibernate.Linq;
оператор в верхней части моего файла. Однако в тот момент, когда я выполняю этот запрос, он не должен зависеть от реализации.
Когда я пытаюсь выполнить модульное тестирование, методы .Fetch
и .ThenFetch
терпят неудачу при выполнении против IQueryable
, который предоставляет мой фиктивный репозиторий.
Как я могу обернуть их внутри моего интерфейса IRepository
или внутри каких-то общих методов расширения?
Обновление:
Пока что все, что я придумал, - это добавьте это в интерфейс моего репозитория:
IQueryable<T> EagerLoadParent<U>(IQueryable<T> query,
Expression<Func<T, U>> parentExpression);
IQueryable<T> EagerLoadParent<U, V>(IQueryable<T> query,
Expression<Func<T, U>> parentExpression,
Expression<Func<U, V>> grandparentExpression);
... и это в мою реализацию репозитория NHibernate:
public IQueryable<T> EagerLoadParent<U>(IQueryable<T> query,
Expression<Func<T, U>> parentExpression)
{
return query
.Fetch(parentExpression);
}
public IQueryable<T> EagerLoadParent<U, V>(IQueryable<T> query,
Expression<Func<T, U>> parentExpression,
Expression<Func<U, V>> grandparentExpression)
{
return query
.Fetch(parentExpression)
.ThenFetch(grandparentExpression);
}
Потребитель этого API теперь делает следующее:
var query =
(from e in repository.AllEntities
where e.SomeProperty == "some value"
select e);
var results = repository
.EagerLoadParent(query, e => e.Parent, p => p.Grandparent)
.ToList();
Но здесь отсутствует красивый синтаксис метода расширения, который я бы предпочел. Я ищу что-то более близкое к синтаксису .Fetch
и .ThenFetch
.