简体   繁体   English

实体框架DBSet非常慢

[英]Entity Framework DBSet is extremely slow

I'm following a n-layered pattern with a services layer. 我遵循带有服务层的n层模式。 No repository layer. 没有存储库层。 The tutorial is http://techbrij.com/service-layer-entity-framework-asp-net-mvc-unit-testing . 该教程是http://techbrij.com/service-layer-entity-framework-asp-net-mvc-unit-testing My problem here is the GetAll() method here is absurdly slow. 我的问题是这里的GetAll()方法非常慢。 It is taking 12 seconds to run a simple paginated query. 运行一个简单的分页查询需要12秒钟。 It seems to be an issue with EFs DBSet , being retrieved by using the _context.Set<T>() method EFs DBSet似乎是一个问题,可以使用_context.Set<T>()方法进行检索

My EntityService 我的EntityService

public class EntityService<T> : IEntityService<T> where T : BaseEntity
{
    protected GraphicContext _context;
    protected DbSet<T> _dbset;

    public EntityService(GraphicContext context)
    {
        _context = context;
        _dbset = _context.Set<T>();
    }


    public virtual async Task CreateAsync(T entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        }

        _dbset.Add(entity);
        await _context.SaveChangesAsync();
    }

    public virtual async Task<T> FindAsync(params object[] keyValues)
    {
        if (keyValues == null)
        {
            throw new ArgumentNullException("id");
        }

        return await _dbset.FindAsync(keyValues);
    }

    public virtual async Task UpdateAsync(T entity)
    {
        if (entity == null) throw new ArgumentNullException("entity");
        _context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
        await _context.SaveChangesAsync();
    }

    public virtual async Task DeleteAsync(T entity)
    {
        if (entity == null) throw new ArgumentNullException("entity");
        _dbset.Remove(entity);
        await _context.SaveChangesAsync();
    }

    public virtual IEnumerable<T> GetAll()
    {
        return _dbset.AsEnumerable<T>();
    }
}

It is using DBSet because after some research IDBSet is obsolete and was also slow on us. 之所以使用DBSet ,是因为经过一番研究, IDBSet已过时并且对我们也很慢。

The table we are accessing has about 300,000 records, but we are using pagination to help the query and for ease of access for the user. 我们正在访问的表大约有300,000条记录,但是我们使用分页来帮助查询并简化用户的访问。 Anyways, To test that it was the call to _context.Set<T>() that is being slow I skipped the service and ran my context in the controller to run the exact same query. 无论如何,为了测试_context.Set<T>()的调用是否缓慢,我跳过了该服务,并在控制器中运行了上下文以运行完全相同的查询。 The query took less than a second. 查询用了不到一秒钟的时间。

Does anyone know why this would be this way or have a way to speed this up? 有谁知道为什么会这样或有办法加快速度? I'm thinking I may have to avoid using the set() method. 我在想可能要避免使用set()方法。 Any other alternatives to this? 还有其他选择吗?

When the result type of GetAll is IEnumerable<T> , all the queries against the result will cause loading the whole table in memory and then querying it via LINQ to Objects. GetAll的结果类型为IEnumerable<T> ,对结果的所有查询将导致将整个表加载到内存中,然后通过LINQ将其查询到Objects。

If you want your queries to be executed at the database (ie via LINQ to Entities), remove AsEnumerable() call and change GetAll type to IQueryable<T> : 如果要在数据库上执行查询(即通过LINQ到Entities),请删除AsEnumerable()调用,并将GetAll类型更改为IQueryable<T>

public virtual IQueryable<T> GetAll()
{
    return _dbset;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM