实体框架上下文在重新创建后保留本地数据



我尝试使用实体框架进行大型插入,因此为了减少上下文膨胀,我尝试每隔x个循环重新创建上下文。然而,在重新创建上下文之后,来自先前上下文的数据仍然在本地信息中。我试着在上下文上调用Dispose((,并在重新创建它之前将其设置为null

我发现以前问过这个问题,哪里有人似乎有同样的问题,但没有找到解决方案。实体框架上下文-重新创建对象将旧对象保留在内存中

ApplicationDbContext context = new ApplicationDbContext();
context.Configuration.AutoDetectChangesEnabled = false;
for (int i = 0; i < products.Count; i++)
{
context.Product.Add(products[i]);
if(i % 50 == 0)
{
context.SaveChanges();
context.Dispose();
context = null;
context = new ApplicationDbContext();
context.Configuration.AutoDetectChangesEnabled = false;
}
}
context.SaveChanges();

上下文产品本地

为了澄清,这就是我在未清除本地数据时的意思。产品的本地数据在本地有151个条目,尽管每50个条目就要重新创建上下文。这导致产品被多次添加到数据库中。

只是为了澄清我在问什么,我如何才能重新创建上下文,使其没有以前上下文遗留的数据?此外,如果有人能解释是什么原因导致数据被保留,那就很好理解了。

编辑:我试着按照Gert Arnold在评论中的建议重新构建代码。这是当前版本。

public void BatchAddProducts(List<ProductModel> products)
{
int loops = (int)Math.Ceiling((double)(products.Count / 50));
List<ProductModel> sublist = new List<ProductModel>();
for (int i = 0; i < loops; i++)
{
int toPull;
if((i * 50 + 50) > products.Count)
{
toPull = products.Count - (i * 50);
}
else
{
toPull = 50;
}
sublist = products.GetRange(i * 50, toPull);
ProductAdd(sublist);
}
}
private void ProductAdd(List<ProductModel> products)
{
using(ApplicationDbContext context = new ApplicationDbContext())
{
context.Product.Local.Clear();
context.Product.AddRange(products);
context.SaveChanges();
}
}

这仍然存在同样的问题。上下文保留了不应再存在的版本中的信息,并且在上一个循环中添加的条目将再次添加到数据库中。即在2次迭代之后150个条目被添加到数据库中,并且在3次迭代之后数据库中有300个新条目。

作为对Steve Py的回答的回应,我正在检查上下文。产品调用SaveChanges((之前的本地信息。我提到的重复数据是上下文中产品的重复数据。因此,参考我之前做的例子,在3个循环之后,第一次迭代中有3个版本的产品,第二次迭代有2个版本,第三次迭代有1个版本。我不认为这是如何生成产品列表的问题。这是我遇到这个问题时的第一个想法,我检查了代码。这段代码是作为改进大型插入的升级而编写的,生成产品的代码是旧的,与旧的更新系统配合良好。此外,传递给函数的列表只有大约8000个产品,所以据我所知,它不可能是这样。

我怀疑您可能会遇到基于语句的不同问题"这导致产品被多次添加到数据库"中;并且验证本地缓存的过程将导致DBSet加载到内存中。

我已经测试了周围的已处理DbContext行为。如果是本地的,并且它的行为符合预期,则先前加载的实体而不是仍被引用。

[Test]
public void TestLocalReset()
{
var context = new TestDbContext();
for (int count = 1; count <= 100; count++)
{
var note = new Note { Text = $"Note #{count}." };
context.Notes.Add(note);
context.SaveChanges();
if (count % 10 == 0)
{
int test = context.Notes.Local.Count; // <- Always 10
context.Dispose();
context = new TestDbContext();
test = context.Notes.Local.Count; // <- Always 0
}
}
context.Dispose();
}

您的示例没有显示您是如何/在哪里检查的。本地实例,但如果您有任何代码查询DbSet,则可能导致将整个结果加载到内存中并显示在中。本地实例。

至于重复的数据,您是得到了重复的产品,还是在您看到重复的产品下面有其他引用的实体?您是如何在阵列中构建/填充这些产品的?当您重新创建DbContext时,将不会跟踪这些新产品要引用的最外层DbContext可能加载的引用,从而导致插入可能重复的相关实体。

您可能需要更新您的问题,以显示您用于创建产品的完整代码,并插入它们,因为这可能包含解释您所看到的行为的详细信息。

最新更新