Ho utilizzato Entity Framework con il primo approccio POCO. Ho praticamente seguito lo schema descritto da Steve Sanderson nel suo libro 'Pro ASP.NET MVC 3 Framework', utilizzando un contenitore DI e una classe DbContext per connettersi a SQL Server.Migliorare l'efficienza con Entity Framework
Le tabelle sottostanti nel server SQL contengono set di dati molto grandi utilizzati da diverse applicazioni. A causa di questo ho dovuto creare una vista per gli enti di cui ho bisogno nella mia domanda:
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");
...
}
}
e questo sembra funzionare bene per la maggior parte dei miei bisogni.
Il problema che ho è che alcuni di questi punti di vista hanno una grande quantità di dati in modo che quando chiamo qualcosa come:
var customers = _repository.Customers().Where(c => c.Location == location).Where(...);
sembra essere riportare l'intero set di dati, che possono Prenditi un po 'di tempo prima che la query LINQ riduca il set a quelli di cui ho bisogno. Questo sembra molto inefficiente quando i criteri sono applicabili solo a pochi record e sto recuperando l'intero set di dati dal server SQL.
ho cercato di ovviare a questo utilizzando stored procedure, come ad esempio
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,...);
}
mentre questo è molto più veloce, il problema qui è che non restituisce un DbSet e così ho perso tutta la connettività tra i miei oggetti, ad es Non posso fare riferimento ad alcun oggetto associato come ordini o contatti anche se includo i loro ID perché il tipo restituito è una raccolta di "Clienti" piuttosto che un DbSet di essi.
Qualcuno ha un modo migliore per far sì che il server SQL esegua l'interrogazione in modo da non passare in giro carichi di dati inutilizzati?
+1. Per ulteriori "approccio estensibile" è possibile scrivere una funzione che richiede un predicato e restituisce '_repository.Customers(). Dove (predicato)' o (se non è IQueryable più) scrivere una funzione separata con 'context.CreateQuery ("Clienti"). Dove (predicato) ', con possibilità di chiamare' .ToList() 'alla fine. Dovrebbe costruire un'espressione piacevole e ottimizzata. –
Ciao. Sei stato azzeccato con il tuo suggerimento di rimanere nel regno di IQueryable. Stavo usando un oggetto IEnumerable che non passa la query al server ma ottiene tutti i record e quindi li filtra. Vedi l'articolo qui: http://www.fascinatedwithsoftware.com/blog/post/2011/06/27/IEnumerable-IQueryable-and-the-Entity-Framework-40.aspx Ho controllato con SQL Profiler e ha ragione, IQueryable passa i parametri come una query – GrahamJRoy