Вопрос

Я не слишком долго работал с SQL, но мне показалось, что я понял, что при заключении операторов SQL в транзакцию выполняются все операторы или ни один из них.Вот моя проблема.У меня есть объект заказа, содержащий коллекцию позиций.Позиции связаны по order.OrderId.Я это проверил все идентификаторы установлены и верны но когда я пытаюсь сохранить (вставить) заказ, который получаю Инструкция INSERT конфликтовала с ограничением FOREIGN KEY «FK_OrderItemDetail_Order».Конфликт произошел в базе данных «MyData», таблица «dbo.Order», столбец «OrderId».

псевдокод:

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

Удачи в решении вашей проблемы.

Другие советы

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

  1. Это очевидно, но ваши две команды вставки находятся в одном и том же соединении (и соединение остается открытым все время), которому принадлежит транзакция, верно?
  2. Получаете ли вы свой идентификатор, связанный с ограничением, после первой вставки и записываете его обратно в данные для второй вставки перед выполнением команды?
  3. Ограничение могло быть установлено неправильно в БД.

Вы определенно не хотите использовать две транзакции.

Похоже, ваш оператор вставки для lineItems неправильно устанавливает значение для заказа.это должно быть результатом Insert order шаг.Просматривали ли вы (и тестировали) отдельные операторы SQL?

Я не думаю, что ваша проблема как-то связана с контролем транзакций.

У меня нет опыта в этом, но похоже, что вы указали значение ключа, которого нет в родительской таблице.Извините, но я не могу вам помочь больше, чем это.

Проблема в том, как вы обрабатываете ошибку.При возникновении ошибки транзакция не откатывается автоматически.Вы, конечно, можете (и, вероятно, должны) сделать это, но в зависимости от вашего приложения или того, где вы находитесь, вы все равно можете захотеть это сделать.И в данном случае это именно то, что вы делаете.Вам нужно обернуть туда некоторый код обработки ошибок, чтобы откатить код при возникновении ошибки.

Ошибка выглядит так, что LineItems не получают должного значения. ФК OrderId который был автоматически сгенерирован при вставке заказа в таблицу заказов.Вы говорите, что проверили идентификаторы. Вы также проверили FK в деталях заказа?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top