Estoy tratando de decidir sobre el mejor patrón para el acceso a los datos en mi aplicación MVC. Actualmente, después de haber seguido la serie de escaparates MVC, estoy usando repositorios, exponiendo IQueryable a una capa de servicio, que luego aplica filtros. Inicialmente he estado utilizando LINQtoSQL, p.¿Deberían los repositorios exponer IQueryable a la capa de servicio o realizar el filtrado en la implementación?
public interface IMyRepository
{
IQueryable<MyClass> GetAll();
}
implementado en:
public class LINQtoSQLRepository : IMyRepository
{
public IQueryable<MyClass> GetAll()
{
return from table in dbContext.table
select new MyClass
{
Field1 = table.field1,
... etc.
}
}
}
filtro para los 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();
}
}
Llamado del servicio:
public class TableService
{
public MyClass RecordsByID(string id)
{
return _repository.GetAll()
.WithID(id);
}
}
me encontré con un problema cuando he experimentado con la aplicación de la repositorio usando Entity Framew ork con LINQ a Entidades. La clase de filtros en mi proyecto contiene algunas operaciones más complejas que el "DONDE ... == ..." en el ejemplo anterior, que creo que requieren diferentes implementaciones dependiendo del proveedor de LINQ. Específicamente, tengo el requisito de realizar una cláusula SQL "DONDE ... EN ...". Soy capaz de implementar esto en la clase de filtro usando:
string[] aParams = // array of IDs
qry = qry.Where(t => aParams.Contains(t.ID));
Sin embargo, con el fin de llevar a cabo esto en contra de Entity Framework, necesito proporcionar una solución como la BuildContainsExpression que está vinculado a Entity Framework. Esto significa que tengo que tener 2 implementaciones diferentes de este filtro en particular, dependiendo del proveedor subyacente.
Agradecería cualquier consejo sobre cómo proceder desde aquí. Me pareció que exponer un IQueryable de mi repositorio me permitiría realizar filtros independientemente del proveedor subyacente, lo que me permite cambiar de proveedor si es necesario. Sin embargo, el problema que describo más arriba me hace pensar que debería realizar todos mis filtros dentro de los repositorios y devolver IEnumerable, IList o clases individuales.
Muchas gracias, Matt
Falsas premisas. 'BuildContainsExpression' es * completamente * independiente del EF (depende solo de Linq y Expressions). También es completamente innecesario en EF 4, que admite 'IEnumerable.Contains' directamente. –