我还有一个关于EF性能的问题。
有一种方法可以从上下文中获取对象:
tDocumentTyp DocumentTypObject = Context.tDocumentTyps.Where(s => s.DocumentTypID == iTypID).FirstOrDefault();
此方法需要约2979毫秒。
然后我写了一个通过反射获取DBSet的方法,并以这种方式执行:
tDocumentTyp DocumentTypObject = Context.GetEntries<tDocumentTyp>().Where(s => s.DocumentTypID == iTypID).FirstOrDefault();
我的方法需要~222 ms才能执行。
所以现在我的问题是,为什么我的方法比原始方法快得多?或者我的方法有什么问题吗?
为了使这更容易,这是我通过反射获取DBSet的方法:
public static IEnumerable<T> GetEntries<T>(this AppContext DataContext,
string PropertyName = null, IEnumerable<string> includes = null) where T : IEntity
{
Type ContextType = typeof(AppContext);
PropertyInfo Entity = null;
if (null == PropertyName)
Entity = ContextType.GetProperty(typeof(T).Name)
?? ContextType.GetProperty(typeof(T).Name + "s");
else
Entity = ContextType.GetProperty(PropertyName);
if (null == Entity)
throw new Exception("Could not find the property. If the property is not equal to the tablesname, you have to parametrize it.");
DbQuery<T> set = ((DbSet<T>)Entity.GetValue(DataContext, null));
if (includes != null)
includes.ForEach(f => set = set.Include(f));
return set;
}
答案 0 :(得分:0)
第二个例子是获取整个表并在内存中应用Where
。您正在应用对System.Linq.Enumerable.Where
进行操作的扩展方法IEnumerable<T>
。请注意,这是一个内存中实现。在第一个示例中,您使用了对System.Linq.Queryable.Where
进行操作的扩展方法IQueryable<T>
。这是一种不同的方法,尽管它们具有相同的名称。
如果仔细检查,您还会发现在第一个示例中,method参数的类型为Expression<Func<T, bool>>
,而在第二个示例中,它只是Func<T, bool>
。这是一个非常重要的区别:可以处理表达式以生成SQL查询。
那么为什么第二个更快呢?好吧,如果没有关于数据源的更多信息,很难回答。但正如其他人在评论中指出的那样,如果数据库没有编入索引,那么选择整个表并在内存中执行过滤器可能比让SQL服务器应用过滤更快。