问题
After having some experience with EF6 (like this), I wanted to try out EF Core, because I've read some articles and watched some videos saying that it outperforms EF6 by a very large margin.
So, I made sample program with class:
public interface IEntity
{
int Id { get; set; }
}
public class Employee : IEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
}
Then I created a repository pattern with generic repository:
public interface IRepository<T> : IDisposable where T : IEntity
{
void Insert(T entity);
void Delete(T entity);
IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
T GetById(int id);
void Update(T entity);
void BeginTransaction();
IDbContextTransaction Transaction { get; }
}
public class Repository<T> : IRepository<T> where T : class, IEntity
{
private RosterContext _context;
private IDbContextTransaction _transaction;
public Repository(bool wrapTransaction = false)
{
_context = new MyContext();
if (wrapTransaction)
{
_transaction = _context.Database.BeginTransaction();
}
}
public void Update(T entity)
{
_context.Set<T>().Update(entity);
_context.SaveChanges();
}
public void BeginTransaction()
{
if (_transaction == null)
_transaction = _context.Database.BeginTransaction();
}
public void Insert(T entity)
{
_context.Set<T>().Add(entity);
_context.SaveChanges();
}
public void Delete(T entity)
{
var toDelete = GetById(entity.Id);
_context.Set<T>().Remove(toDelete);
_context.SaveChanges();
}
public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
{
return _context.Set<T>().AsNoTracking().Where(predicate);
}
public IQueryable<T> GetAll()
{
return _context.Set<T>().AsNoTracking();
}
public T GetById(int id)
{
return _context.Set<T>().AsNoTracking().FirstOrDefault(x => x.Id == id);
}
public IDbContextTransaction Transaction => _transaction;
public void Dispose()
{
_transaction?.Dispose();
_context?.Dispose();
}
}
And this is context:
public class MyContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
public MyContext()
{
Database.Migrate();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=test.db");
}
}
As you can see, this is the simplest sample that there can be: one table, one entity with 2 properties stored in SQLite. The problem is, that first query takes almost 5 seconds with 10 rows in database. Next ones are instant.
I work on computer with SSD drive and i5 processor.
What is the problem? Is it SQLite? Is it Database.Migrate();
(if I comment this line it does not change anything)? Or all performance improvements are just bad?
回答1:
Actually the problem occurs only while debugging. The cause is that Entity Framework throws and catches thousands of exceptions, and they slow down the debugger. See the GitHub issue here.
To solve it I enabled "Enable Just My Code" option in Tools -> Options -> Debugging -> General. That way Visual Studio does not trace the exceptions from Entity Framework.
来源:https://stackoverflow.com/questions/49353909/ef-core-2-1-slow-startup