Używam Entity Framework z POCO First approach. Podążałem za wzorcem opisanym przez Steve Sandersona w jego książce "Pro ASP.NET MVC 3 Framework", używając kontenera DI i klasy DbContext do połączenia z serwerem SQL.Poprawa wydajności dzięki Entity Framework
Podstawowe tabele w serwerze SQL zawierają bardzo duże zestawy danych używane przez różne aplikacje. Z tego powodu musiałem utworzyć widoki dla podmiotów, których potrzebuję w mojej aplikacji:
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");
...
}
}
i to wydaje się dobrze dla większości moich potrzeb.
Mam problem jest, że niektóre z tych poglądów mają wiele danych w nich tak, że gdy zgłoszę coś takiego:
var customers = _repository.Customers().Where(c => c.Location == location).Where(...);
wydaje się być przywrócenie całego zestawu danych, które mogą poświęć trochę czasu, zanim zapytanie LINQ zmniejszy zestaw do tych, których potrzebuję. Wydaje się to bardzo nieefektywne, gdy kryteria mają zastosowanie tylko do kilku rekordów i otrzymuję cały zestaw danych z serwera SQL.
Próbowałem to obejść za pomocą procedur przechowywanych, takich jak
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,...);
}
podczas gdy jest to o wiele szybciej, problemem jest to, że nie zwraca DbSet i tak stracę wszystkie z łączność między moimi obiektami, np Nie mogę odwoływać się do żadnych powiązanych obiektów, takich jak zamówienia lub kontakty, nawet jeśli zawieram ich identyfikatory, ponieważ typem zwracanym jest kolekcja "Klienci", a nie DbSet z nich.
Czy ktoś ma lepszy sposób na uzyskanie serwera SQL do wykonywania zapytań, tak aby nie przekazywać mnóstwa nieużywanych danych?
+1. Aby uzyskać bardziej "rozszerzalne podejście", możesz napisać funkcję, która pobiera predykat, i zwraca '_repository.Customers(). Gdzie (predicate)' lub (jeśli nie jest już IQueryable) napisać osobną funkcję z 'context.CreateQuery ("Klienci"). Gdzie (predykat) ', z możliwością wywołania' .ToList() 'na końcu. Powinien stworzyć ładną, zoptymalizowaną ekspresję. –
Witam. Byłeś na miejscu z twoją sugestią pozostania w królestwie IQueryable. Używałem IEnumerable, który nie przekazuje kwerendy do serwera, ale pobiera wszystkie rekordy, a następnie filtruje je. Zobacz artykuł tutaj: http://www.fascinatedwithsoftware.com/blog/post/2011/06/27/IEnumerable-IQueryable-and-the-Entity-Framework-40.aspx Sprawdziłem z SQL Profiler i ma rację, IQueryable przekazuje parametry jako zapytanie – GrahamJRoy