EF 4.3.1 and EF 5.0 DbSet.Local is slower than an actual Database query

谁说我不能喝 提交于 2019-11-30 06:15:01

Why don't you simply save List of string from first query and use that instead.

List<string> cities = db.Cities.Select( x=>x.CityName).ToList();

Local may be slower because of Select, which might be doing some consistency checks.

I walked the source for the Local property using Resharper's handy feature. You'll first see a call to DetectChanges which probably isn't your issue if all you're running is the above three lines. But then EF creates a new ObservableCollection for Local and fills it item by item. Either of those can be costly on the first call.

The query directly against the DbSet will route into the EF database providers which I'm sure directly access the internal local cache.

The following extension method will return an IEnumerable<T> containing the DbSet's local cached entities without the startup overhead incurred by the DbSet.Local() method detecting context changes and creating an ObservableCollection<T> object.

<Extension()>
Public Function QuickLocal(Of T As Class)(ByRef DbCollection As DbSet(Of T)) As IEnumerable(Of T)
    Dim baseType = DbCollection.[GetType]().GetGenericArguments(0)
    Dim internalSet = DbCollection.GetType().GetField("_internalSet", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance).GetValue(DbCollection)
    Dim internalContext = internalSet.GetType().GetProperty("InternalContext").GetValue(internalSet, Nothing)
    Return DirectCast(internalContext.GetType.GetMethod("GetLocalEntities").MakeGenericMethod(baseType).Invoke(internalContext, Nothing), IEnumerable(Of T))
End Function

Calling .QuickLocal on a DbSet containing 19,679 entities takes 9 ms, whereas calling .Local takes 2121 ms on the first call.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!