Я пытаюсь выбрать лучший шаблон для доступа к данным в моем приложении MVC.
В настоящее время, следуя серии витрин магазина MVC, я использую репозитории, выставляя IQueryable на сервисный уровень, который затем применяет фильтры. Первоначально я использовал LINQtoSQL, например
public interface IMyRepository
{
IQueryable<MyClass> GetAll();
}
Реализовано в:
public class LINQtoSQLRepository : IMyRepository
{
public IQueryable<MyClass> GetAll()
{
return from table in dbContext.table
select new MyClass
{
Field1 = table.field1,
... etc.
}
}
}
Фильтр для идентификаторов:
public static class TableFilters
{
public static MyClass WithID(this IQueryable<MyClass> qry, string id)
{
return (from t in qry
where t.ID == id
select t).SingleOrDefault();
}
}
Вызывается из службы:
public class TableService
{
public MyClass RecordsByID(string id)
{
return _repository.GetAll()
.WithID(id);
}
}
Я столкнулся с проблемой, когда экспериментировал с реализацией репозитория с использованием Entity Framework с LINQ to Entities. Класс filters в моем проекте содержит некоторые более сложные операции, чем «WHERE ... == ...» в приведенном выше примере, который, я считаю, требует разных реализаций в зависимости от поставщика LINQ. В частности, у меня есть требование выполнить предложение SQL "WHERE ... IN ...". Я могу реализовать это в классе фильтра, используя:
string[] aParams = // array of IDs
qry = qry.Where(t => aParams.Contains(t.ID));
Однако, чтобы выполнить это с Entity Framework, мне нужно предоставить решение, такое как BuildContainsExpression , которое связано с Entity Framework. Это означает, что у меня должно быть 2 разных реализации этого конкретного фильтра, в зависимости от основного поставщика.
Буду признателен за любые советы о том, как мне поступить отсюда.
Мне казалось, что предоставление IQueryable из моего хранилища позволит мне выполнять фильтрацию на нем независимо от основного поставщика, что позволяет мне переключаться между поставщиками, если и когда это потребуется. Однако проблема, которую я описал выше, заставляет меня думать, что я должен выполнить всю свою фильтрацию в репозиториях и вернуть IEnumerable, IList или отдельные классы.
Большое спасибо,
Matt