He estado utilizando Entity Framework con el primer enfoque de POCO. He seguido bastante el patrón descrito por Steve Sanderson en su libro 'Pro ASP.NET MVC 3 Framework', usando un contenedor DI y una clase DbContext para conectarme a SQL Server.Mejorando la eficiencia con Entity Framework
Las tablas subyacentes en el servidor SQL contienen conjuntos de datos muy grandes utilizados por diferentes aplicaciones. Debido a esto he tenido que crear vistas para las entidades que necesito en mi solicitud:
class RemoteServerContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<Contact> Contacts { get; set; }
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>().ToTable("vw_Customers");
modelBuilder.Entity<Order>().ToTable("vw_Orders");
...
}
}
y esto parece que funciona bien para la mayoría de mis necesidades.
El problema que tengo es que algunos de estos puntos de vista tienen una gran cantidad de datos en ellos para que cuando llamo algo como:
var customers = _repository.Customers().Where(c => c.Location == location).Where(...);
parece que está trayendo de vuelta todo el conjunto de datos, lo que puede tómese un tiempo antes de que la consulta LINQ reduzca el conjunto a los que necesito. Esto parece muy ineficiente cuando el criterio solo es aplicable a unos pocos registros y recupero todo el conjunto de datos del servidor SQL.
me han tratado de evitar esto mediante el uso de procedimientos almacenados, tales como
public IEnumerable<Customer> CustomersThatMatchACriteria(string criteria1, string criteria2, ...) //or an object passed in!
{
return Database.SqlQuery<Customer>("Exec pp_GetCustomersForCriteria @crit1 = {0}, @crit2 = {1}...", criteria1, criteria2,...);
}
mientras que esto es mucho más rápido, el problema aquí es que no devuelve un DbSet y por lo que pierde toda la conectividad entre mis objetos, por ejemplo No puedo hacer referencia a ningún objeto asociado, como pedidos o contactos, incluso si incluyo sus ID porque el tipo de devolución es una colección de 'Clientes' en lugar de un DbSet de ellos.
¿Alguien tiene una forma mejor de hacer que SQL Server haga las consultas para que no esté pasando mucha información no utilizada?
+1. Para obtener más 'enfoque extensible' puede escribir una función que toma un predicado y devuelve ya sea '_repository.Customers(). Where (predicate)' o (si ya no es IQueryable) escriba una función separada con 'context.CreateQuery ("Clientes"). Donde (predicado) ', con posibilidad de invocar' .ToList() 'al final. Debería construir una expresión agradable y optimizada. –
Hola. Has notado tu sugerencia de mantenerte en el reino de IQueryable. Estaba usando un IEnumerable que no pasa la consulta al servidor pero obtiene todos los registros y luego los filtra. Vea el artículo aquí: http://www.fascinatedwithsoftware.com/blog/post/2011/06/27/IEnumerable-IQueryable-and-the-Entity-Framework-40.aspx Lo he consultado con SQL Profiler y él tiene razón, IQueryable pasa los parámetros como una consulta – GrahamJRoy