在获得EF6的一些经验(如this)之后,我想尝试使用EF Core,因为我已经阅读了一些文章并观看了一些视频,说它的表现超过了EF6。
所以,我用课程制作了示例程序:
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; }
}
然后我创建了一个带有通用存储库的存储库模式:
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();
}
}
这是背景:
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");
}
}
正如您所看到的,这是最简单的示例:一个表,一个实体,其中有2个属性存储在SQLite中。问题是,第一个查询在数据库中占用10行需要将近5秒。接下来是即时的。
我在配备SSD驱动器和i5处理器的计算机上工作。
有什么问题?是SQLite吗?它是Database.Migrate();
(如果我评论这一行它不会改变任何东西)?或者所有性能改进都很糟糕?
答案 0 :(得分:4)
实际上,该问题仅在调试时发生。原因是Entity Framework引发并捕获了数千个异常,并且它们减慢了调试器的速度。请参阅GitHub问题here。
要解决此问题,我在工具->选项->调试->常规中启用了“仅启用我的代码”选项。这样,Visual Studio不会跟踪来自Entity Framework的异常。