Я предпочитаю использовать табличный подход для большинства конечных автоматов:
typedef enum { STATE_INITIAL, STATE_FOO, STATE_BAR, NUM_STATES } state_t;
typedef struct instance_data instance_data_t;
typedef state_t state_func_t( instance_data_t *data );
state_t do_state_initial( instance_data_t *data );
state_t do_state_foo( instance_data_t *data );
state_t do_state_bar( instance_data_t *data );
state_func_t* const state_table[ NUM_STATES ] = {
do_state_initial, do_state_foo, do_state_bar
};
state_t run_state( state_t cur_state, instance_data_t *data ) {
return state_table[ cur_state ]( data );
};
int main( void ) {
state_t cur_state = STATE_INITIAL;
instance_data_t data;
while ( 1 ) {
cur_state = run_state( cur_state, &data );
// do other program logic, run other state machines, etc
}
}
Это может, конечно, быть расширено для поддержки нескольких конечных автоматов и т.д. Действия перехода могут быть размещены также:
typedef void transition_func_t( instance_data_t *data );
void do_initial_to_foo( instance_data_t *data );
void do_foo_to_bar( instance_data_t *data );
void do_bar_to_initial( instance_data_t *data );
void do_bar_to_foo( instance_data_t *data );
void do_bar_to_bar( instance_data_t *data );
transition_func_t * const transition_table[ NUM_STATES ][ NUM_STATES ] = {
{ NULL, do_initial_to_foo, NULL },
{ NULL, NULL, do_foo_to_bar },
{ do_bar_to_initial, do_bar_to_foo, do_bar_to_bar }
};
state_t run_state( state_t cur_state, instance_data_t *data ) {
state_t new_state = state_table[ cur_state ]( data );
transition_func_t *transition =
transition_table[ cur_state ][ new_state ];
if ( transition ) {
transition( data );
}
return new_state;
};
табличный подход легче поддержать и расшириться и более простой отобразиться на диаграммы состояний.
Тааак, в чем была причина проблемы - Триггер
Я создал профилировщик sql и увидел, что
Когда свойство DeletedOn объекта ObjY обновлялось, обновлялся триггер. Свойство ObjX (значение в таблице) под названием CountOfX
, которое привело к ошибке, поскольку SQL, созданный LINQ to SQL, содержал в себе старое значение CountOfX.
Отсюда конфликт.
Если вы когда-нибудь получите эту ошибку - Профилировщик SQL - лучшее место для начала расследования
ТАКЖЕ НЕ ОТНОСИТСЯ К ВОПРОСУ Я тестирую LINQ to SQL и ADO.net Framework, как ни странно, эта ошибка произошла в LINQ to SQL, но не в платформе ADO.net. Но мне нравится LINQ to SQL за его отложенную загрузку. Ожидание выхода EF из бета-версии
Я не уверен, в чем именно может быть причина ошибки, но есть кажется, есть ряд проблем с приведенным вами примером.
Использование ToList () перед методом Where () приведет к тому, что ваш контекст прочитает всю таблицу из БД в память, преобразует ее в массив; а затем в той же строке вы немедленно вызываете Where, который отбрасывает строки, которые вы загрузили, но не нужны. Почему не просто:
_context.X.Where (...
Метод Where вернет несколько элементов, но вторая строка в примере не ' Кажется, что t повторяется по каждому элементу индивидуально. Похоже, что для самой коллекции устанавливается свойство DeletedOn, но у коллекции не было бы такого свойства. Он должен сразу же выйти из строя.
Вы дважды используете DateTime.Now в коде. Это не проблема, за исключением того, что при каждом вызове значения даты будут немного отличаться. Вы должны вызвать DateTime.Now один раз и присвоить результат переменной, чтобы все, с чем вы его используете, получило идентичные значения.
В точке, где у вас есть «Y objY = objYs [0]», он завершится ошибкой, если нет элементы в коллекции Y для любого заданного X. Вы получите исключение индекса за пределами диапазона для массива.
Учитывая этот пример, я не уверен, что кто-нибудь может предположить, почему код, смоделированный на основе этого примера, может давать сбой.
Похоже, что для самой коллекции устанавливается свойство DeletedOn, но у коллекции не было бы такого свойства. Он должен сразу же выйти из строя.Вы дважды используете DateTime.Now в коде. Это не проблема, за исключением того, что при каждом вызове значения даты будут немного отличаться. Вы должны вызвать DateTime.Now один раз и присвоить результат переменной, чтобы все, с чем вы его используете, получило идентичные значения.
В точке, где у вас есть «Y objY = objYs [0]», он завершится ошибкой, если нет элементы в коллекции Y для любого заданного X. Вы получите исключение индекса за пределами диапазона для массива.
Учитывая этот пример, я не уверен, что кто-нибудь может предположить, почему код, смоделированный на основе этого примера, может давать сбой.
Похоже, что для самой коллекции устанавливается свойство DeletedOn, но у коллекции не было бы такого свойства. Он должен сразу же выйти из строя.Вы дважды используете DateTime.Now в коде. Это не проблема, за исключением того, что при каждом вызове значения даты будут немного отличаться. Вы должны вызвать DateTime.Now один раз и присвоить результат переменной, чтобы все, с чем вы его используете, получило идентичные значения.
В точке, где у вас есть «Y objY = objYs [0]», он завершится ошибкой, если нет элементы в коллекции Y для любого заданного X. Вы получите исключение индекса за пределами диапазона для массива.
Учитывая этот пример, я не уверен, что кто-нибудь может предположить, почему код, смоделированный на основе этого примера, может давать сбой.
но у коллекции не было бы такого свойства. Он должен сразу же выйти из строя.Вы дважды используете DateTime.Now в коде. Это не проблема, за исключением того, что при каждом вызове значения даты будут немного отличаться. Вы должны вызвать DateTime.Now один раз и присвоить результат переменной, чтобы все, с чем вы его используете, получило идентичные значения.
В точке, где у вас есть «Y objY = objYs [0]», он завершится ошибкой, если нет элементы в коллекции Y для любого заданного X. Вы получите исключение индекса за пределами диапазона для массива.
Учитывая этот пример, я не уверен, что кто-нибудь может предположить, почему код, смоделированный на основе этого примера, может давать сбой.
но у коллекции не было бы такого свойства. Он должен сразу же выйти из строя.Вы дважды используете DateTime.Now в коде. Это не проблема, за исключением того, что при каждом вызове значения даты будут немного отличаться. Вы должны вызвать DateTime.Now один раз и присвоить результат переменной, чтобы все, с чем вы его используете, получило идентичные значения.
В точке, где у вас есть «Y objY = objYs [0]», он завершится ошибкой, если нет элементы в коллекции Y для любого заданного X. Вы получите исключение индекса за пределами диапазона для массива.
Учитывая этот пример, я не уверен, что кто-нибудь может предположить, почему код, смоделированный на основе этого примера, может давать сбой.
за исключением того, что это будет приводить к слегка разным значениям даты при каждом вызове. Вы должны вызвать DateTime.Now один раз и присвоить результат переменной, чтобы все, с чем вы его используете, получило идентичные значения.В точке, где у вас есть «Y objY = objYs [0]», он завершится ошибкой, если нет элементы в коллекции Y для любого заданного X. Вы получите исключение индекса за пределами диапазона для массива.
Учитывая этот пример, я не уверен, что кто-нибудь может предположить, почему код, смоделированный на основе этого примера, может давать сбой.
за исключением того, что это будет приводить к слегка разным значениям даты при каждом вызове. Вы должны вызвать DateTime.Now один раз и присвоить результат переменной, чтобы все, с чем вы его используете, получило идентичные значения.В точке, где у вас есть «Y objY = objYs [0]», он завершится ошибкой, если нет элементы в коллекции Y для любого заданного X. Вы получите исключение индекса за пределами диапазона для массива.
Учитывая этот пример, я не уверен, что кто-нибудь может предположить, почему код, смоделированный на основе этого примера, может давать сбой.
он завершится ошибкой, если в коллекции Y нет элементов для любого заданного X. Вы получите исключение индекса за пределами массива.Учитывая этот пример, я не уверен, что кто-нибудь может предположить, почему код, смоделированный на основе этого примера, может давать сбой.
он завершится ошибкой, если в коллекции Y нет элементов для любого заданного X. Вы получите исключение индекса за пределами массива.Учитывая этот пример, я не уверен, что кто-нибудь может предположить, почему код, смоделированный на основе этого примера, может давать сбой.