我一直在使用實體框架和POCO First方法。我幾乎遵循Steve Sanderson在他的書「Pro ASP.NET MVC 3 Framework」中描述的模式,使用DI容器和DbContext類連接到SQL Server。使用實體框架提高效率
SQL服務器中的基礎表包含由不同應用程序使用的非常大的數據集。正因爲如此,我不得不創建視圖的,我需要在我的應用程序中的實體:
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");
...
}
}
,這似乎爲我的大部分需求,做工精細。
我的問題是,其中的一些觀點在他們的數據大量這樣,當我打電話是這樣的:
var customers = _repository.Customers().Where(c => c.Location == location).Where(...);
它似乎被帶回整個數據集,從而可以
在LINQ查詢將集合減少到我需要的集合之前需要一些時間。當條件僅適用於幾條記錄時,這看起來非常低效,而且我正在從SQL Server獲取整個數據集。
我曾嘗試通過使用存儲過程來解決這個問題,比如
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,...);
}
,而這是要快得多,這裏的問題是,它不返回DbSet,所以我失去了所有的我的對象之間的連接,例如即使我包含他們的ID,我也不能引用任何關聯對象,例如訂單或聯繫人,因爲返回類型是'Customers'的集合,而不是它們的DbSet集合。
有沒有人有更好的方式讓SQL服務器執行查詢,以便我不傳遞大量未使用的數據?
+1。對於更多'可擴展的方法',你可以編寫一個接受謂詞的函數,並且返回'_repository.Customers()。Where(predicate)'或者(如果它不再是IQueryable),用'context.CreateQuery 「Customers」)。where(predicate)',最後可能調用'.ToList()'。它應該構建一個很好的,優化的表達式。 –
嗨。你的建議是留在IQueryable領域。我正在使用IEnumerable,它不會將查詢傳遞給服務器,而是獲取所有記錄,然後對其進行過濾。看到這裏的文章:http://www.fascinatedwithsoftware.com/blog/post/2011/06/27/IEnumerable-IQueryable-and-the-Entity-Framework-40.aspx我檢查了SQL事件探查器,他是正確的, IQueryable作爲查詢傳遞參數 – GrahamJRoy