Ошибка транзакции структуры сущностей после удаления строки и вставки новой строки с тем же первичным ключом - PullRequest
2 голосов
/ 25 мая 2011

Я использую ASP.NET MVC2 в Visual Studio 2008. Я считаю, что SQL Server 2005. Я использую Entity Framework для доступа к базе данных.

У меня есть следующая таблица с составным первичнымключ на основе iRequest и sCode:

RequestbyCount
    iRequest  integer
    sCode     varchar(10)
    iCount    integer

iRequest является внешним ключом для списка запросов.

Когда запрос обновляется, я хочу очиститьсуществующий RequestbyCounts для этого запроса, а затем добавить новый RequestbyCounts.Скорее всего, единственная разница между старыми строками - это Count.

Для моего кода я пытаюсь сделать это следующим образом:

//delete ALL our old requests
var oldEquipList = (from eq in myDB.dbEquipmentRequestedbyCountSet
                    where eq.iRequestID == oldData.iRequestID
                    select eq).ToList();
foreach (var oldEquip in oldEquipList)
{
     myDB.DeleteObject(oldEquip);
}

//  myDB.SaveChanges();    <---- adding this line makes it work

//add in our new requests
foreach (var equip in newData.RequestList)   //newData.RequestList is a List object
{
   if (equip.iCount > 0)
   {
    //add in our actual request items
      RequestbyCount reqEquip = new RequestbyCount();
      reqEquip.sCodePrefix = equip.sCodePrefix;
      reqEquip.UserRequest = newRequest;
      reqEquip.iCount = equip.iCount;
      myDB.AddToRequestbyCount(reqEquip);
   }
}

myDB.SaveChanges();   //save our results

Проблема заключается в том, что я запускаю его спромежуточная SaveChanges строка без комментариев, работает по желанию.Но я понимаю, что это разрушает транзакцию.

Если я оставлю промежуточные SaveChanges закомментированными, как указано выше, процесс завершится неудачно, и я получу

Нарушение ограничения PRIMARY KEY 'PK_RequestbyCount'.Невозможно вставить повторяющийся ключ в объект 'dbo.RequestbyCount'. \ R \ nОпределение завершено.

Очевидно, что без выполнения промежуточного SaveChanges старые строки НЕ удаляются по желанию.

Я не хочу, чтобы результаты сохранялись, пока все не выполнится.

Я бы не стал использовать следующий подход:

//add in our new requests
foreach (var equip in newData.RequestList)
{
   if (equip.iCount > 0) && (**it isn't in the database**)
   {
    //add in our actual request items
      RequestbyCount reqEquip = new RequestbyCount();
      reqEquip.sCodePrefix = equip.sCodePrefix;
      reqEquip.UserRequest = newRequest;
      reqEquip.iCount = equip.iCount;
      myDB.AddToRequestbyCount(reqEquip);
   } else if (**it is in the database**) && (equip.iCount == 0) {
      **remove from database**
   } else {
      **edit the value in the database**
   }
}

Я застрял, выполняя приведенный выше код, который в основном делаеткуча маленьких звонков в базу данных, чтобы проверить, существует ли элемент?

Или есть какой-то метод, который указывает платформе попытаться удалить нужные мне строки, но выполнить откат в случае сбоя при вставке новых строк?

1 Ответ

2 голосов
/ 25 мая 2011

Вы не используете транзакции вообще.Вам нужно обернуть весь свой код в

using (TransactionScope transaction = new TransactionScope())
{
    ...
    transaction.Complete();
}

Еще лучше

using (TransactionScope transaction = new TransactionScope())
{
    try
    { 
       your code 
       transaction.Complete();
    }
    catch(Exception)
    {
       // handle error
    }
}

Использование блока try / catch гарантирует, что транзакция не будет зафиксирована, если произойдет исключение, что и являетсяВы заявили, что хотели.

Подробнее о транзакциях в рамках структуры сущностей на веб-сайте Microsoft .Объяснения там довольно хорошие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...