Как Вы обходите несколько соединений с базой данных в TransactionScope, если MSDTC отключен?

Используя NSTextFields с привязками, Какао использует методы кодирования значения ключа (KVC), такие как setValue:forKey:. Установки привязок в Storyboard / XIB всегда связаны с объектом подкласса NSObject (контроллером). Необъектные значения обрабатываются специально:

Если ваш объект, совместимый с кодировкой значений ключей, получает сообщение setValue:forKey: с нулевым значением, переданным в качестве значения для необъектного свойства, реализация по умолчанию не имеет соответствующей Обобщенный курс действий. Поэтому он отправляет себе setNilValueForKey: сообщение, которое вы можете переопределить. Реализация по умолчанию setNilValueForKey: вызывает исключение NSInvalidArgumentException, но вы можете обеспечить соответствующее, специфичное для реализации поведение.

blockquote>

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/HandlingNon-ObjectValues.html#//apple_ref/doc/uid/10000107i-CH5- SW1

В вашем случае OrderFormViewController не было переопределено setNilValueForKey: метод, и это вызвало исключение.

Реализация setNilValueForKey: решит все проблемы.

PS: использование NSNumberFormatter или привязка к объекту NSNumber также решит проблему.

6
задан Joseph 17 April 2009 в 18:08
поделиться

2 ответа

Хорошо, я нашел способ обойти эту проблему. Единственная причина, по которой я делаю это таким образом, заключается в том, что я не мог найти ЛЮБОГО другого способа решения этой проблемы, и потому что это в моих интеграционных тестах, поэтому я не беспокоюсь о том, что это окажет неблагоприятное влияние на производственный код. ] Мне пришлось добавить свойство в мой DataContext, чтобы действовать в качестве флага, чтобы отслеживать, нужно ли удалять объект соединения, когда мой DataContext удаляется. Таким образом, соединение сохраняется во всей области транзакции, и, следовательно, больше не беспокоит DTC.

Вот пример моего нового Dispose:

internal static bool SupressConnectionDispose { get; set; }

public void Dispose()
{
   if (Connection.State == ConnectionState.Open)
   {
       Connection.ChangeDatabase(
           DatabaseInfo.GetDatabaseName(OriginalDatabase));
   }

   if (Connection != null 
       && --ConnectionReferences <= 0 
       && !SuppressConnectionDispose)
   {
       if (Connection.State == ConnectionState.Open)
           Connection.Close();
       Connection.Dispose();
   }
}

это позволяет моим интеграционным тестам принимать форму:

[Test]
public void WorkflowExampleTest()
{
    (using var transaction = new TransactionScope())
    {
        DataContext.SuppressConnectionDispose = true;

        Presenter.ProcessWorkflow();
    }
}

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

1
ответ дан 17 December 2019 в 18:19
поделиться

Если вы не хотите использовать MSDTC, вы можете использовать транзакции SQL напрямую.

См. SqlConnection.BeginTransaction () .

0
ответ дан 17 December 2019 в 18:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: