实体框架的性能

本文关键字:性能 框架 实体 | 更新日期: 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.WhereIQueryable<T> 上运行。这是一种不同的方法,尽管它们共享相同的名称。

如果仔细检查,您还会发现在第一个示例中,方法参数的类型为 Expression<Func<T, bool>>,而在第二个示例中,它只是 Func<T, bool> 。这是一个非常重要的区别:可以处理表达式以生成 SQL 查询。

那么为什么第二个更快呢?好吧,如果没有有关数据源的更多信息,这很难回答。但正如其他人在注释中指出的那样,如果数据库没有索引,那么选择整个表并在内存中执行过滤器可能比让 SQL 服务器应用过滤更快。