实体框架的性能
本文关键字:性能 框架 实体 | 更新日期: 2023-09-27 18:31:12
我还有一个关于 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 毫秒才能执行。
所以我现在的问题是,为什么我的方法比原来的方法快得多?还是我的方法有什么问题?
为了使这更容易一些,这是我通过反射获取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;
}
第二个示例是获取整个表并在内存中应用Where
。您正在应用在IEnumerable<T>
上运行的扩展方法System.Linq.Enumerable.Where
。请注意,这是一个内存中实现。在第一个示例中,您使用扩展方法System.Linq.Queryable.Where
在IQueryable<T>
上运行。这是一种不同的方法,尽管它们共享相同的名称。
如果仔细检查,您还会发现在第一个示例中,方法参数的类型为 Expression<Func<T, bool>>
,而在第二个示例中,它只是 Func<T, bool>
。这是一个非常重要的区别:可以处理表达式以生成 SQL 查询。
那么为什么第二个更快呢?好吧,如果没有有关数据源的更多信息,这很难回答。但正如其他人在注释中指出的那样,如果数据库没有索引,那么选择整个表并在内存中执行过滤器可能比让 SQL 服务器应用过滤更快。