使用LINQ逐个插入多个记录

时间:2016-03-21 10:11:57

标签: c# asp.net-mvc linq

我正在尝试将ProductStatisticsTemp表数据复制到ProductStatistics表,

var str = from a in db.ProductStatisticsTemp select a;

ProductStatistics ls = new ProductStatistics();

foreach (var val in str.ToList())
{                     
     ls.Product_ID = val.Product_ID;
     ls.ProductNameEn = val.ProductNameEn;
     ls.ProductNameAr = val.ProductNameAr;

     db.ProductStatistics.Add(ls);
     db.SaveChanges();
}

第一条记录可以插入但是一旦尝试插入第二条记录就会出现以下错误

  

属性'Product_ID'是对象的关键信息的一部分   无法修改。

3 个答案:

答案 0 :(得分:2)

这是因为您有一个对象实例,并尝试两次添加已添加的对象。

您需要在循环中创建ProductStatistics的新对象。

此外,您只需在循环后保存一次更改,即可通过触发器数据库通信一次性提高性能:

var str = from a in db.ProductStatisticsTemp select a;

foreach (var val in str.ToList())
{                     
     ProductStatistics ls = new ProductStatistics
     {
         Product_ID = val.Product_ID,
         ProductNameEn = val.ProductNameEn,
         ProductNameAr = val.ProductNameAr
     };

     db.ProductStatistics.Add(ls);
}

db.SaveChanges();

答案 1 :(得分:1)

这是一种略有不同的方法。

var products = db.ProductStatisticsTemp.Select(t => new ProductStatistics
                             {
                                 Product_ID = t.Product_ID,
                                 ProductNameEn = t.ProductNameEn,
                                 ProductNameAr = t.ProductNameAr
                             }).ToList()

db.ProductStatistics.AddRange(products);
db.SaveChanges();       

答案 2 :(得分:0)

恕我直言从@Vadim Martynov启发

  

如果 Product_ID 是您的主键,并且您的设置要增加   来自数据库的关键。不要这样做Product_ID = val.Product_ID。   密钥应该从数据库生成。你会得到身份证   保存更改后调用。

 try
 {
   var str = from a in db.ProductStatisticsTemp select a;

   //This will improve some performance
   db.Configuration.AutoDetectChangesEnabled = false;

   foreach (var val in str.ToList())
   {                     
      ProductStatistics ls = new ProductStatistics
      {

         Product_ID = val.Product_ID,
         ProductNameEn = val.ProductNameEn,
         ProductNameAr = val.ProductNameAr
     };

     //use AddRange or Add based on your EF Version.
     db.ProductStatistics.Add(ls);
   }

  db.SaveChanges();
 }
 finally
 {
      db.Configuration.AutoDetectChangesEnabled = true;
 }
  

如果您使用的是AddRange,则可以省略db.Configuration.AutoDetectChangesEnabled = false

有关DetectChanges可用here

的更多信息
  

AddRange()方法仅支持EF6,请参阅documentation

db.ProductStatistics.AddRange(products);
  

AddRange将为您做什么

如果AutoDetectChangesEnabled is set to true(这是默认值),则在添加任何实体之前将调用一次DetectChanges,并且不会再次调用。

  

这意味着在某些情况下,AddRange可能会显着执行   比多次调用Add更好。

请注意,已处于某个其他状态的上下文中的实体的状态将设置为“已添加”。对于已经处于已添加状态的上下文中的实体,AddRange是一个无操作。