2016-04-06 19 views
0

Bir hizmet katmanına sahip n katmanlı bir desen takip ediyorum. Depo katmanı yok. Öğretici http://techbrij.com/service-layer-entity-framework-asp-net-mvc-unit-testing. Benim sorunum burada GetAll() yöntemidir, işte saçma bir şekilde yavaştır. Basit bir paginated sorguyu çalıştırmak için 12 saniye sürüyor. IDBSet eskimiş ve aynı zamanda bize yavaş çünkü sonra biraz araştırma O DBSet kullanıyor _context.Set<T>() yöntemiEntity Framework DBSet son derece yavaş

Benim 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>(); 
    } 
} 

kullanarak alınmakta EFS DBSet ile ilgili bir sorun olduğu görülüyor.

Erişmekte olduğumuz tablo yaklaşık 300.000 kayıt içeriyor, ancak sorgulamaya ve kullanıcı için erişim kolaylığı sağlamak amacıyla sayfalama kullanıyoruz. Her neyse, bu yavaş olduğunu _context.Set<T>() çağrı olduğunu test etmek için hizmet atlandı ve aynı sorguyu çalıştırmak için denetleyicide bağlamımı çalıştı. Sorgu bir saniyeden az sürdü.

Bunun neden böyle olacağını veya bunu hızlandırmak için bir yolu olduğunu bilen var mı? Ben düşünüyorum set() yöntemini kullanmaktan kaçınmak zorunda kalabilirsiniz. Buna başka alternatifler var mı?

+1

mesele' DbSet' değil, ama:

size sorguları AsEnumerable() çağrıyı kaldırıp GetAll tip IQueryable<T> değiştirmek (varlıkları için yani LINQ yoluyla) veritabanına yürütülecek istiyorsanız AsEnumerable'. Ve genel olarak 'GetAll' sonucunun IEnumerable 'türü. Bu şekilde, bellekte tüm tabloyu her zaman okuyacak ve LINQ to Objects ile belleğe karşı sorguları çalıştıracaksınız. –

+0

Aslında 'AsEnumerable ()' ı kaldırdım ve sadece 'NoTracking()' ile değiştirdim. Sorguyu 3 saniye hızlandırdı. Yine de –

+2

'u çalıştırmak için yaklaşık 8 veya 9 saniye sürdü. Ancak, 'GetAll' türünü de değiştirmeniz gerekiyor, aksi halde efekt, 'AsEnumerable' çağrısıyla aynıdır. Örneğin. IQueryable GetAll ' –

cevap

3

GetAll sonuç türü IEnumerable<T> olduğunda, sonuca yönelik tüm sorgular belleğin tüm tablosunun yüklenmesine ve ardından LINQ ile Objects aracılığıyla sorgulanmasına neden olur. `

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

Bunun için teşekkürler. –

+0

Bir şey değil. Ve son yorum için özür dileriz, yanlışlıkla size hitap etti :) –