2016-03-21 3 views
-1

Я пытаюсь скопировать ProductStatisticsTemp таблицы данных в таблице ProductStatistics,вставка нескольких записей по одному с помощью LINQ

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(); 
} 

первая запись может вставить, но как только его попытки вставить 2-ым получать следующие ошибки

Свойство 'Product_ID' является частью ключевой информации объекта и не может быть изменено.

+4

Вам нужно переместить 'ProductStatistics ls = new ProductStatistics();' внутрь цикла (и вы можете перемещать 'db.SaveChanges();' после цикла). –

+0

Если вы хотите использовать один и тот же объект, тогда все его свойства должны быть сброшены, –

ответ

2

Это потому, что у вас есть один экземпляр объекта и попытайтесь добавить уже добавленный объект дважды.

В петле необходимо создать новый объект 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(); 
+0

, но как сохранить данные в таблице по строкам, а не сразу? – kez

+0

@kez главный вопрос: в чем причина? Вы можете вызвать SaveChanges внутри цикла, но результат будет таким же, и у вас будет дополнительная загрузка на канал связи. –

+0

как только я вставляю внутренний цикл 'SaveChanges', я получаю ошибку' Произошла ошибка при запуске транзакции в соединении с провайдером. См. Внутреннее исключение для деталей. ' – kez

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();  
0

ИМХО Вдохновленный из @Vadim Мартынова

Если 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 может выполнять значительно лучше, чем позвонить. Добавление нескольких раз.

Обратите внимание, что объекты, которые уже находятся в контексте в каком-либо другом состоянии, будут иметь свой статус в Добавлен. AddRange - это no-op для объектов, которые уже находятся в контексте в добавленном состоянии.

Смежные вопросы