Okay, I know I have to be doing something wrong here because the performance times I’m getting are so different its shocking. I’ve been considering using the code first option of entity in an existing project of mine so I’ve been trying to do some performance test just to see how it compares. I’m using MSpec to run the tests against a remote development database.
Here are my tests:
public class query_a_database_for_a_network_entry_with_linq : ipmanagement_object {
protected static NetINFO.IPM_NetworkMaster result;
Because of = () => {
var db = new NetINFODataContext();
result = db.IPM_NetworkMasters.SingleOrDefault(c => c.NetworkID == 170553);
};
It should_return_an_ipm_networkmaster_object = () => {
result.ShouldBeOfType(typeof(NetINFO.IPM_NetworkMaster));
};
It should_return_a_net_ou_object_with_a_networkid_of_4663 = () => {
result.IPM_OUIDMaps.First().NET_OU.NET_OUID.ShouldEqual(4663);
};
}
public class query_a_database_for_a_network_entry_with_entity_code_first : ipmanagement_object {
protected static NetInfo.Core.Models.CTP.IPM_NetworkMaster result;
Because of = () => {
NetInfo.Core.Models.CTP.NetInfoDb db = new NetInfo.Core.Models.CTP.NetInfoDb();
result = db.IPM_NetworkMasters.SingleOrDefault(c => c.NetworkID == 170553);
};
It should_return_an_ipm_networkmaster_object = () => {
result.ShouldBeOfType(typeof(NetInfo.Core.Models.CTP.IPM_NetworkMaster));
};
It should_return_a_net_ou_object_with_a_networkid_of_4663 = () => {
result.NET_OUs.First().NET_OUID.ShouldEqual(4663);
};
}
As you can see from the datacontext with linq-to-sql I can’t access object directly that have a many to many relationship. I have to use the intermediate lookup table. Which is one of the things I like about Entity framework. However when I run these test the linq test never takes longer than 4 seconds to complete (database is remote). Where the entity test takes almost 8 seconds every time. Not for sure why there is such a huge difference?? Here is excerpts of my POCO classes and my dbcontext:
DbContext:
public class NetInfoDb : DbContext {
public NetInfoDb() : base("NetINFOConnectionString") { }
public DbSet<IPM_NetworkMaster> IPM_NetworkMasters { get; set; }
public DbSet<IPM_NetworkType> IPM_NetworkTypes { get; set; }
public DbSet<NET_OU> NET_OUs { get; set; }
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) {
modelBuilder.Entity<IPM_NetworkMaster>()
.HasMany(a => a.NET_OUs)
.WithMany(b => b.IPM_NetworkMasters)
.Map(m => {
m.MapRightKey(a => a.NET_OUID, "NET_OUID");
m.MapLeftKey(b => b.NetworkID, "NetworkID");
m.ToTable("IPM_OUIDMap");
});
}
}
IPM_NetworkMaster:
public class IPM_NetworkMaster {
public int NetworkID { get; set; }
<snip>
public virtual ICollection<NET_OU> NET_OUs { get; set; }
}
NET_OU:
public class NET_OU {
public int NET_OUID { get; set; }
<snip>
public virtual ICollection<IPM_NetworkMaster> IPM_NetworkMasters { get; set; }
}
As everyone has mentioned, you need to profile your queries. Assuming you are using SQL Server, you can just spool up SQL Server Profiler and compare the queries and execution plans.
As with any performance issue, you must measure first. With your scenario, you have to do more. You have to measure twice with each technology and make sure you are comparing apples to apples. If you can rule out the sql being generated you will then have to measure the application code, to possibly rule any bottlenecks there.
I suspect it will be the generated queries though.