我有兩種方法通過其Id找到實體。第一個使用IQueryable對象通過其Id使用lambda表達式查找對象,另一個使用內置的Entity Framework DbSet.Find()方法。我在Visual Studio中編寫了幾個單元測試,爲兩種方法創建速度基準,以確定哪一種更好用。實體框架6 DbSet.Find效率
有趣的是,我寫的方法比在Find中構建的實體框架獲得更好的結果。有誰知道爲什麼?
下面是實體框架方法的代碼:
public virtual T Find<T>(int id)
{
return dbContext.Set<T>().Find(id);
}
這裏是我的方法的代碼:
public virtual T FindById<T>(int id)
{
return dbContext.Set<T>().Where(x => x.IsActive).AsQueryable().FirstOrDefault(x => x.Id == id);
}
這裏是花了對於選擇它們中的每一個時間從DB幾個記錄:
這是我的測試課程:
[TestClass]
public class EntityBenchmarks
{
EdiDataStore target;
[TestInitialize]
public void Start()
{
target = new EdiDataStore();
}
[TestCleanup]
public void Cleanup()
{
target.Dispose();
}
//this method is only here because i want to make sure that the
//database context is loaded into memory so that we can compare
//Find and FindById on an even scale. Without this method, the first
//time benchmark that runs is hit with the overhead of loading the model.
[TestMethod]
public void Control()
{
var entities = target.GetAgencies();
}
[TestMethod]
public void FindBenchmark()
{
bool isSuccess = true;
for (int i = 9177; i <= 9187; i++)
{
var entity = target.Find<Spot>(i);
isSuccess = isSuccess && entity != null;
}
Assert.IsTrue(isSuccess);
}
[TestMethod]
public void FindByIdBenchmark()
{
bool isSuccess = true;
for (int i = 9177; i <= 9187; i++)
{
var entity = target.FindById<Spot>(i);
isSuccess = isSuccess && entity != null;
}
Assert.IsTrue(isSuccess);
}
}
你確定你的基準測試是正確的嗎?如果您先撥打「FindByIdBenchmark」,什麼時間? –
@Pawel在他的回答中說過的所有內容,以及您還需要考慮DB。查詢計劃和結果可以緩存在數據庫中,以查看是否有可能影響結果的任何內容。如果它們不同,您可能必須分析生成的查詢。要做到這一點,你需要使用sql profiler。比較時,不要忘記刷新SQL Server緩存。 – Igor
請參閱我的原始文章以進行編輯以包含我的測試課程。這兩個測試執行的順序不是一個因素,因爲我有控制方法來加載模型。另外,如果您注意到,由於TestInitialize和TestCleanup方法的設置DbContext的方式相同,所以這兩個函數都會受到影響 – AKirby50