我一直在測試實體框架,以便更好地理解它,並瞭解它如何有效地用作查詢數據庫的後端設備。提高實體框架查詢的性能
作爲參考,我知道實體框架默認使用延遲加載。對於我試圖創建的後端系統,這是沒有用的。
int x = 0;
using (SandboxContext dbc = new SandboxContext()) {
var customers = (from c in dbc.Customer orderby c.AcctNumber select new { c.CustomerKey, c.AcctNumber }).ToList();
var products = (from p in dbc.Product orderby p.CustomerKey select new { p.CustomerKey }).ToList();
foreach (var c in customers)
foreach (var p in products.Where(s => s.CustomerKey == c.CustomerKey))
++x;
dbc.Dispose();
}
return x;
這是相當於我目前使用的代碼。
我試過的一切似乎只會惡化該方法的性能。作爲參考,此代碼在我的機器上執行大約5秒鐘,以返回大約22000個自動生成數據的計數。此代碼,在另一方面運行幾乎在瞬間爲相同的結果:
SqlConnection sqlc = new SqlConnection(sqlConnectString);
SqlDataAdapter sqlda = new SqlDataAdapter("SELECT customerkey, acctnumber FROM customers", sqlc);
DataTable dtCustomers = new DataTable(), dtProducts = new DataTable();
sqlda.Fill(dtCustomers);
sqlda.SelectCommand.CommandText = "SELECT customerkey FROM product";
sqlda.Fill(dtProducts);
sqlda.Dispose();
sqlc.Close();
DataView dvCustomers = new DataView(dtCustomers) { Sort = "AcctNumber" };
DataView dvProducts = new DataView(dtProducts) { Sort = "CustomerKey" };
int x = 0;
for (int y = 0; y < 1000; y++)
foreach (DataRowView drvCustomers in dvCustomers) {
DataRowView[] drvaProducts = dvProducts.FindRows(drvCustomers["customerkey"].ToString());
foreach (DataRowView drvProducts in drvaProducts)
++x;
}
return x;
我遠遠更喜歡實體框架代碼的整潔性和可讀性,但我認爲我失去了一些信息的重要一塊是顯著傷害了我方法的速度。有什麼想法來改進實體框架代碼,以至少接近DataTable/DataView/DataRowView實現的速度?
應該採取什麼'x'值表示? – dotctor
如果您的模型中有所有必需的互惠屬性(即'Customer'包含'Product'集合),那麼您嘗試執行的操作應該與'dbc.Customer.SelectMany(c => c。產品).Count之間的()'。如果你的'客戶'沒有'產品'集合,那麼考慮設置一個......沒有這個,你會錯過許多EF優點。 – spender
首先,EF有一個預熱成本,它建立了用於構建SQL的模型。 https://msdn.microsoft.com/en-us/library/bb896240(v=vs.100).aspx其次,你擊中數據庫兩次。您可以使用未來的查詢來防止這種情況發生。 https://lostechies.com/jimmybogard/2014/03/11/efficient-querying-with-linq-automapper-and-future-queries/ –