在我的应用程序中,有时需要在一次操作中将10,000行或更多行保存到数据库中.我发现简单地迭代并一次添加一个项目可能需要花费半个多小时.
但是,如果我禁用AutoDetectChangesEnabled它需要约5秒(这正是我想要的)
我正在尝试向DbSet创建一个名为"AddRange"的扩展方法,该方法将禁用AutoDetectChangesEnabled,然后在完成时重新启用它.
public static void AddRange<TEntity>(this DbSet<TEntity> set, DbContext con, IEnumerable<TEntity> items) where TEntity : class
{
// Disable auto detect changes for speed
var detectChanges = con.Configuration.AutoDetectChangesEnabled;
try
{
con.Configuration.AutoDetectChangesEnabled = false;
foreach (var item in items)
{
set.Add(item);
}
}
finally
{
con.Configuration.AutoDetectChangesEnabled = detectChanges;
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是:有没有办法从DbSet获取DbContext?我不喜欢把它作为参数 - 感觉它应该是不必要的.
有很多关于如何在 Entity Framework 中禁用延迟加载的帖子,但相同的技术在 EF Core 中不起作用。我LazyLoadingEnabled在更改跟踪器中找到了该属性,但这似乎根本不起作用。
EF 中的一切都指向了这一点:
this.Configuration.LazyLoadingEnabled = false;
Run Code Online (Sandbox Code Playgroud)
但是,ConfigurationEF Core 中缺少该属性。
这是我正在谈论的一个例子:
public class TestContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<Address> Addresses { get; set; }
public TestContext()
{
this.ChangeTracker.LazyLoadingEnabled = false;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connection = new SqliteConnection($"Data Source=Test.db");
connection.Open();
var command = connection.CreateCommand();
command.CommandText = $"PRAGMA foreign_keys = ON;";
command.ExecuteNonQuery();
optionsBuilder.UseSqlite(connection);
optionsBuilder.UseLazyLoadingProxies(false);
base.OnConfiguring(optionsBuilder);
}
private static void Main(string[] args) …Run Code Online (Sandbox Code Playgroud) 对于EF6,我在我的通用存储库中有一个方法,我将其暴露给所有服务层,以便根据需要使用任何嵌套属性从数据库中检索实体:
public IQueryable<T> OldMethod(params Expression<Func<T, object>>[] includeProperties)
{
var queryable = set.AsQueryable();
return includeProperties.Aggregate(queryable, (current, includeProperty) => current.Include(includeProperty));
}
Run Code Online (Sandbox Code Playgroud)
这样,我可以通过以下方式使用该方法:
var data = repo.OldMethod(x => x.Papers, => x.People.Select(y => y.Addresses)).ToList();
Run Code Online (Sandbox Code Playgroud)
在EF6中,这将加载每个人的Papers导航属性,People导航属性和Addresses导航属性.正如预期的那样,这会在EFCore中引发异常.由于在EFCore中切换到Include - > ThenInclude方法,我不太清楚如何在我的服务层轻松复制它,我不想要任何有关EntityFramework的信息.