实体框架真的很慢获得单一项目

Big*_*ddy 3 c# entity-framework iqueryable asp.net-web-api

从包含6,000条记录的表中获取单个项目大约需要30秒.显然,这是不可接受的,我无法弄清楚为什么.我的堆栈是.NET 4.5,EF 6和Web API 2.我做的事情有什么明显的错误吗?

// DbSet
internal DbSet<TEntity> _dbSet;

// Ctor
public GenericRepository(TContext context)
        {
            _context = context;
            _context.Configuration.ProxyCreationEnabled = false;
            _dbSet = _context.Set<TEntity>();
        }

// Really slow method
public TEntity GetByFilter(Func<TEntity,bool> filter, params Expression<Func<TEntity, object>>[] includes)
        {
            IQueryable<TEntity> query = _dbSet;
            if (includes != null)
            {
                foreach (var include in includes)
                    query = query.Include(include);
            }

            var entity = query.Where(filter).FirstOrDefault();

            return entity;
        }

// Here's how it's called.  It returns a single item
var x = _unitOfWork.Repository.GetByFilter(i => i.WinId == id, null);
Run Code Online (Sandbox Code Playgroud)

Mat*_*hew 8

这很慢的原因是你在你的Where子句中使用linq-to-objects ,这意味着你在客户端(C#)而不是服务器(SQL)上执行谓词,C#正在接收6000个数据库记录,然后过滤它在记忆中.

您可以看到这一点,因为您的filter参数是类型Func,这意味着您通过IEnumerable.Where扩展名使用linq-to-objects .

相反,您想要使用的是IQueryable.Where扩展,它接受类型的参数Expression.这使用了Entity Framework查询提供程序,因此使用了linq-to-ef.

更新您的方法签名如下:

public TEntity GetByFilter(
    Expression<Func<TEntity,bool>> filter, 
    params Expression<Func<TEntity, object>>[] includes)
Run Code Online (Sandbox Code Playgroud)

这在下面的stackoverflow答案/sf/answers/55550911/中进一步说明