我一直在测试实体框架,以便更好地理解它,并了解它如何有效地用作查询数据库的后端设备。提高实体框架查询的性能
作为参考,我知道实体框架默认使用延迟加载。对于我试图创建的后端系统,这是没有用的。
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/ –