我正在尝试在我的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.
}
}
}
过滤ID:
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);
}
}
当我尝试使用带有LINQ to Entities的实体框架实现存储库时,我遇到了一个问题。我的项目中的过滤器类包含一些比上面示例中的“WHERE ... == ...”更复杂的操作,我认为这需要不同的实现,具体取决于LINQ提供程序。具体来说,我需要执行SQL“WHERE ... IN ...”子句。我可以使用以下方法在过滤器类中实现:
string[] aParams = // array of IDs
qry = qry.Where(t => aParams.Contains(t.ID));
但是,为了针对Entity Framework执行此操作,我需要提供一个解决方案,例如 BuildContainsExpression 这与实体框架有关。这意味着我必须有2个不同的特定过滤器实现,具体取决于底层提供程序。
我很感激有关如何从这里开始的任何建议。 在我看来,从我的存储库中公开IQueryable将允许我对其执行过滤器而不管底层提供者,使我能够在需要时在提供者之间切换。但是我上面描述的问题让我觉得我应该在存储库中执行所有过滤并返回IEnumerable,IList或单个类。
非常感谢, 马特