DBContext(实体框架)和预加载的实体

时间:2015-02-18 12:50:44

标签: asp.net-mvc entity-framework ef-code-first entity

我首先在Web应用程序中使用代码,我有一个表单来上传文本文件并将数据导入我的数据库。 每个文件最多可包含20.000+条记录以供导入。 为了加快速度,我预加载了一些实体,所以不要每次都询问DbContext。然后,当我创建一个插入对象时,我会这样做:

myNewObject.Category = preloadedCategories.First(p => p.Code == code);

我在网上看过一些文章,因为EF在批量插入时非常慢,所以我所做的是:

  1. 首先使用Configuration.AutoDetectChangesEnabled = false;
  2. 然后每1000条记录我处理该对象并创建一个新对象。
  3. BUT!由于预先加载的实体是从处理的db上下文加载的,因此在创建新的DbContext之后,我遇到了preloadedCategories.First(p => p.Code == code)的问题。当我创建SaveChanges()时,EF会尝试保存preloadedCategories.First(p => p.Code == code)对象并失败。

    那么我该如何实现呢?我不希望每次都加载DbContext来加载一些(不变的)对象。有可能吗?

    感谢

1 个答案:

答案 0 :(得分:0)

在处理EF中的大量记录时,有一些事情会有所帮助

  1. 如@janhartmann所述,请使用.AsNoTracking()
  2. 如您所述,使用Configuration.AutoDetectChangesEnabled = false,这将需要下一个点
  3. 使用context.Categories.Entry(category).State = EntityState.Modified将断开连接的实体附加到上下文并将标记修改为
  4. 还要检查preloadedCategories是否不再是IQuerable,并且数据确实是本地数据,而不是尝试从数据库延迟加载。

    如果您的Category对象没有变化,而您只是想将myNewObject与现有类别相关联,那么您有两个选择

    1. myNewObject而不是导航属性
    2. 上设置外键
    3. 使用context.Products.Entry(myNewObject).State = EntitySate.Added代替context.Products.Add(myNewObject),以避免添加整个导航属性图
    4. 祝你好运