Транзакции в LINQ To SQL

Я использую LINQ To SQL и вызываю хранимые процедуры для вставки новых строк.

  1. Демонстрирует ли приведенный ниже код соответствующий набор шагов?
  2. Я хочу вставить (другие четверки), только если все четыре вставки пройдены, иначе откатить все четыре вставки.
public bool InsertNewInquiry(Inquiry inq)
{
    using (var transaction = new TransactionScope())
    {
        using (DataContextDataContext dc = conn.GetContext())
        { 
            foreach (Officer po in inq.Recipients)
            {
                int results1 =  (int)dc.**spOffice_Insert**(po.Id,po.Name).ReturnValue;
            }
            foreach (Lookups tags in inq.Tags)
            {
                int results2 =  (int)dc.**spTags_Insert**(po.Id,po.Name).ReturnValue;
            }

            foreach (Phone phone in inq.Phone)
            {
                int results3 =  (int)dc.**spPhone_Insert**(po.Id,po.Name).ReturnValue;
            }

            int results4 =  (int)dc.spInquiry_Insert(
                            inq.Id
                            ,inq.StatusId
                            ,inq.PriorityId
                            ,inq.Subject).ReturnValue;                  


          if (results1 != 0 && results2 != 0 && results3 != 0 && results4 != 0)
          {
              transaction.Complete();
              return true;
          }
          return false;

           /* old code:
            transaction.Complete();    
            if (results == 0)
                return false;
            else
                return true;  */
        }
    }
}

Я пробовал приведенный выше код, но он не вставляет вставку foreach (results1...results3)

Любая идея, как я могу заставить эту работу работать по желанию?


person Nick Kahn    schedule 13.08.2010    source источник


Ответы (2)


Рассмотрим решение, где:

  • изменить область ваших результатов
  • если результат 0 является условием для любого из ваших 3 foreach, для которого вы абсолютно хотите выполнить откат, не увеличивайте его, как показано ниже. Просто проверьте 0 и break вне foreach.
int res1=0, res2=0, res3=0, res4=0;
foreach (Officer po in inq.Recipients)
{
    res1 += (int)dc.**spOffice_Insert**(po.Id,po.Name).ReturnValue;
}
foreach (Lookups tags in inq.Tags)
{
    res2 += (int)dc.**spTags_Insert**(po.Id,po.Name).ReturnValue;
}
foreach (Phone phone in inq.Phone)
{
    res3 += (int)dc.**spPhone_Insert**(po.Id,po.Name).ReturnValue;
}
res4 += (int)dc.spInquiry_Insert(inq.Id,inq.StatusId,inq.PriorityId,inq.Subject)
                 .ReturnValue;                  

//no results are zero
if (res1 != 0 && res2 != 0 && res3 != 0 && res4 != 0)
{
    transaction.Complete();
    return true;
}
return false;
person p.campbell    schedule 17.08.2010
comment
Это выглядит примерно так, хотя мне интересно, хотят ли они откатиться, если какое-либо из ReturnValue чисел равно 0. - person Steven Sudit; 17.08.2010
comment
Я думаю, что если какие-либо результаты вернутся 0, вы захотите откатиться. - person Kelsey; 18.08.2010

TransactionScope это правильный путь, на мой взгляд. У меня было похожий вопрос относительно транзакций в Linq To SQL некоторое время назад. Хотя это не одна и та же проблема, ответы, которые я получил, должны предоставить вам полезную информацию.

Основываясь на том, что я могу сказать из вашего кода, вы не учитываете четыре возвращаемых результата перед вызовом transaction.Complete();. Оператор Complete() зафиксирует вашу транзакцию, поэтому вы хотите убедиться, что все правильно, прежде чем вызывать это аналогично тому, как вы использовали бы COMMIT в SQL.

person Kelsey    schedule 14.08.2010
comment
@Nisar Khan, вы должны обновить свой код фактическим кодом, потому что только с той частью, которую вы добавили, я понятия не имею, как это работает, поскольку значения result1, result2 и result3 будут вне области действия, поскольку они созданы в foreach и вы будете сравнивать только с самым последним результатом возврата записей. Кроме этого, код выглядит так, как будто он должен быть зафиксирован. Вы пытались запустить профилировщик SQL, чтобы увидеть, выполняются ли операторы? - person Kelsey; 17.08.2010