实体框架6,创建新实体非常慢

时间:2015-06-22 14:37:46

标签: c# entity-framework entity-framework-6

我有一个方法可以读取文本文件,解析它并从我的数据库中创建(或更新)实体。 代码很简单: 1-读取/解析文件并创建列表 在此列表中的2-循环,首先查看是否找到了产品,如果没有,则创建它。 3-更新属性 4-在循环外保存上下文

问题在于,在循环的每次迭代中,创建部分(if中的部分)需要越来越长的时间。

我的问题是: 这是将实体添加到上下文的最佳方法吗? 这可以以某种方式得到改善吗?

我对实体框架很陌生,不确定我是否正确使用它。 顺便说一句,上下文是在调用方法中创建的。

谢谢你的建议。

CODE:

  public void ImportProduct(MyContext context, string sourceFile)
  {
  List<Product> newProducts = ParseItems(sourceFile);
  var currentProductsMap = context.Products.ToDictionary(x => x.OriginalId, x => x);
  foreach (var item in newProducts)
  {
    var id = item.OriginalId;
    Product product;
    if (!currentProductsMap.TryGetValue(id, out product))
    {
        product = context.Products.Create();
        product.OriginalId = id;
        context.Products.Add(product);
    }
    product.UPC = string.Empty;
  }
  context.SaveChanges();
   }

3 个答案:

答案 0 :(得分:0)

好吧,所以减速的明显原因是Entity Framework只在你的foreach完成后才提交数据,这意味着你可以轻松收集比你的应用程序缓冲更多的数据。一个简单的解决方法是在循环的常规间隔中调用提交/保存,看看这是否会发生任何变化。跟踪你的内存使用情况!

在您开始深入了解EF优化之前,我建议您查看Entity Framework Bulk Insert,它是为快速插入大量数据而设计的。

答案 1 :(得分:0)

以下行可能会导致您的问题:

product = context.Products.Create();

MSDN link表示&#34;为此集的类型创建实体的新实例。请注意,此实例未添加或附加到集合。如果基础上下文配置为创建代理并且实体类型满足创建代理的要求,则返回的实例将是代理。&#34;

所以,似乎有可能为动态代理创建做了额外的工作,你可能没想到。

也许你应该再尝试一下:

var product = new Product();

答案 2 :(得分:0)

  public void ImportProduct(string file)
    {
        using (var context = new LaceupDatabase()) {
            context.Configuration.AutoDetectChangesEnabled = false;
            if (context == null)
                return;
            List<Product> products = ParseItems(file);
            var productMap = context.Products.ToDictionary(x => x.OriginalId, x => x);
            foreach (var item in products) {
                var id = item.OriginalId;
                Product product;
                bool modified = false;
                bool newItem = false;
                if (!productMap.TryGetValue(id, out product)) {
                    product = new Product();
                    product.OriginalId = id;
                    modified = true;
                    newItem = true;
                }
                else
                    // This is a reference to another entity
                    if (product.Category != null && item.Category != null && product.Category.Id != item.Category.Id) {
                        context.Configuration.AutoDetectChangesEnabled = true;
                        product.Category = item.Category;
                        // product.CategoryId = item.Category.Id;
                        modified = false;
                        context.SaveChanges();
                        context.Configuration.AutoDetectChangesEnabled = false;
                    }
                if (newItem || product.Code != item.Code) {
                    product.Code = item.Code;
                    modified = true;
                }
                if (newItem) {
                    context.Products.Add(product);
                    context.Entry(product).State = System.Data.Entity.EntityState.Added;
                }
                else
                    if (modified)
                        context.Entry(product).State = System.Data.Entity.EntityState.Modified;
            }
            context.SaveChanges();
        }
  }

你好,

这是我目前正在测试的代码,我还在使用AutoDetectChangesEnabled = false,因为它是最大的性能提升者。 这需要的问题是,如果实体被更改为将其标记为已修改,我必须跟踪。

最大的问题是实体类型的一个属性的情况,由于某种原因,即使将实例标记为已修改,属性也没有被更新,所以我最终需要将AutoDetectChangesEnabled设置为true,进行更改和坚持到DB。

同样,代码远非漂亮,但它似乎有效地执行,到目前为止没有失败。

如果有人有其他建议,我会非常感激。

感谢, 伊格纳西奥