Я слишком долго не работал в SQL, но мне казалось, что я понял, что, обернув SQL-запросы внутри транзакции, все завершенные заявления или ни один из них не сделал. Вот моя проблема. У меня есть объект заказа, который имеет коллекцию lineitem. Позиции связаны с порядком. ORDERId. Я подтвердил, что все идентификаторы установлены и правильны, но когда я пытаюсь сохранить (вставить) порядок, я получаю . Оператор INSERT противоречил ограничению FOREIGN KEY "FK_OrderItemDetail_Order". Конфликт произошел в базе данных "MyData", таблице "dbo.Order", в столбце "OrderId".
код psuedo:
create a transaction transaction.Begin() Insert order Insert order.LineItems <-- error occurs here transaction.Commit
действительный код:
... entity.Validate(); if (entity.IsValid) { SetChangedProperties(entity); entity.Install.NagsInstallHours = entity.TotalNagsHours; foreach (OrderItemDetail orderItemDetail in entity.OrderItemDetailCollection) { SetChangedOrderItemDetailProperties(orderItemDetail); } ValidateRequiredProperties(entity); TransactionManager transactionManager = DataRepository.Provider.CreateTransaction(); EntityState originalEntityState = entity.EntityState; try { entity.OrderVehicle.OrderId = entity.OrderId; entity.Install.OrderId = entity.OrderId; transactionManager.BeginTransaction(); SaveInsuranceInformation(transactionManager, entity); DataRepository.OrderProvider.Save(transactionManager, entity); DataRepository.OrderItemDetailProvider.Save(transactionManager, entity.OrderItemDetailCollection); if (!entity.OrderVehicle.IsEmpty) { DataRepository.OrderVehicleProvider.Save(transactionManager, entity.OrderVehicle); } transactionManager.Commit(); } catch { if (transactionManager.IsOpen) { transactionManager.Rollback(); } entity.EntityState = originalEntityState; } } ...
Кто-то предложил мне использовать две транзакции: одну для заказа и одну для позиций, но я уверен, что это неправильно. Но я боролся с этим уже более дня, и мне нужно его решить, чтобы я мог двигаться дальше, даже если это означает, что вы плохо работаете. Может, я просто делаю что-то глупое?
Я заметил, что вы сказали, что используете NetTiers для генерации кода.
Я сам использовал NetTiers и обнаружил, что если вы удалите ограничение внешнего ключа из своей таблицы, добавьте его обратно в ту же таблицу, а затем запустите сценарии сборки для NetTiers снова после внесения изменений в базу данных, возможно, w70 > уровень доступа к данным. Я иногда пробовал это с положительными результатами.
Удачи вам в вашей проблеме.
Не видя своего кода, трудно сказать, в чем проблема. Это может быть любое количество вещей, но посмотрите на них:
Вы определенно не хотите использовать две транзакции.
Похоже, что ваш оператор insert для lineItems неправильно устанавливает значение для заказа. Это должно быть результатом шага Insert order
. Вы посмотрели (и протестировали) отдельные инструкции SQL?
Я не думаю, что ваша проблема имеет какое-то отношение к управлению транзакциями.
Проблема заключается в том, как вы обрабатываете ошибку. При возникновении ошибки транзакция автоматически откатывается. Вы можете (и, вероятно, должны) это сделать, но в зависимости от вашего приложения или того, где вы находитесь, вы все равно можете его совершить. И в этом случае это именно то, что вы делаете. Вам нужно обернуть некоторый код обработки ошибок, чтобы отбросить ваш код при возникновении ошибки.
У меня нет опыта с этим, но похоже, что вы указали значение ключа, которое недоступно в родительской таблице. Извините, но я не могу помочь вам больше, чем это.
Ошибка выглядит так, что в LineItems не задан правильный FK OrderId, который был автогенерирован вводом заказа в таблицу заказов. Вы говорите, что вы проверили идентификаторы, вы также проверили FK в деталях заказа?