C# 使用LINQ逐个插入多个记录
我正在尝试将C# 使用LINQ逐个插入多个记录,c#,asp.net-mvc,linq,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;
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”是对象关键信息的一部分,并且
无法修改
这是因为您有一个对象实例,并尝试添加两次已添加的对象 您需要在循环中创建
ProductStatistics
的新对象
此外,您还可以在循环后仅保存一次更改,以通过仅触发一次DB通信来提高性能:
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();
这里有一个稍微不同的方法
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();
IMHO的灵感来自@Vadim Martynov 如果
产品ID
是您的主键,并且设置为递增
数据库中的密钥。不要这样做Product\u ID=val.Product\u ID
。
应该从数据库生成密钥。你会拿到身份证的
调用保存更改后
如果使用的是AddRange
,则可以省略db.Configuration.AutoDetectChangesEnabled=false
有关检测更改的更多信息,请参见
AddRange()方法仅支持EF6,请参阅
AddRange将为您做的是
如果将AutoDetectChangesEnabled设置为true(这是默认设置),则在添加任何实体之前将调用一次DetectChanges,并且不会再次调用
这意味着在某些情况下,AddRange的性能可能会显著提高
比多次调用Add要好
请注意,已经处于其他状态的上下文中的实体将其状态设置为“添加”。AddRange对于已处于添加状态的上下文中的实体是不可操作的。您需要移动
ProductStatistics ls=new ProductStatistics()
到循环内部(您可以将db.SaveChanges();
移动到循环之后)。如果要使用同一对象,则必须重置其所有属性,但如何将数据逐行保存到表中,而不是一次?@kez主要问题是:原因是什么?您可以在循环内调用SaveChanges,但结果将是相同的,您将有额外的通信通道加载。一旦我在循环内插入SaveChanges
,我将收到错误在提供程序连接上启动事务时出错。查看内部异常以了解详细信息。
最好的方法是查看内部异常以了解详细信息。没有可能导致此错误的问题,我们需要更多信息来回答您的问题。另外,我很抱歉,steel不明白为什么需要分别保存每一行。我只想保存已验证的结果,不想插入无效的其他结果
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;
}
db.ProductStatistics.AddRange(products);