I've been testing Entity Framework to try to understand it better and see how it can be used effectively as a back-end device to query a database.
For reference, I know that Entity Framework uses lazy loading by default. For a back-end system like the one that I am trying to create, this is not useful.
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;
This is code equivalent to what I am currently using.
Everything that I have tried seems to only worsen the performance of the method. For reference, this code executes for around 5 seconds on my machine to return a count of around 22000 pieces of auto-generated data. This code, on the other hand runs almost instantaneously for the same result:
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;
I far prefer the cleanliness and readability of the Entity Framework code, but I think that I'm missing some crucial piece of information that's significantly hurting the speed of my method. Any thoughts to improve the Entity Framework code to at least get close to the speed of the DataTable/DataView/DataRowView implementation?
xvalue represents?Customerhas a collection ofProduct), what you are trying to do should be as easy asdbc.Customer.SelectMany(c => c.Products).Count(). If yourCustomerdoesn't have a collection ofProduct, then consider setting one up... you'll be missing out on a lot of EF goodness without this.dbc.Customer.SelectMany(c => c.Products).Count()will give you a count of all products related to customers in a single query without having to ship all the join data locally.Customer.Products(or whatever it's called) property, EF will do joins for you without having to be explicit. I'd consider using a join to be an anti-pattern when EF is set up to do it for you.