У меня есть сага, в которой есть 3 состояния -
public static State Initial { get; set; }
public static State ReceivingRows { get; set; }
public static State Completed { get; set; }
Он переходит от Initial к ReceiveRows, когда получает BofMessage (где Bof = начало файла). После BofMessage он получает большое количество сообщений RowMessage, каждое из которых описывает строку в плоском файле. После отправки всех RowMessages отправляется EofMessage, и состояние изменяется на Completed. Наблюдать -
static void DefineSagaBehavior()
{
Initially(When(ReceivedBof)
.Then((saga, message) => saga.BeginFile(message))
.TransitionTo(ReceivingRows));
During(ReceivingRows, When(ReceivedRow)
.Then((saga, message) => saga.AddRow(message)));
During(ReceivingRows, When(ReceivedRowError)
.Then((saga, message) => saga.RowError(message)));
During(ReceivingRows, When(ReceivedEof)
.Then((saga, message) => saga.EndFile(message))
.TransitionTo(Completed));
}
public override void OnAddRow(ParcelRowMessage message)
{
// ensure isCauvReturned is "Y"
var fields = message.Value;
var isCauvReturned = fields[33] == "Y";
if (!isCauvReturned)
return;
// add row with just parcel number
var parcelNumber = fields[1];
var row = parcelNumber;
_rows.Add(row);
}
Это работает, за исключением того, что у него производительность n-squared. Исследование с помощью NHProf показывает, что каждая добавленная строка приводит к тому, что весь список строк выглядит следующим образом:
А) выбрано из базы данных
Б) удалить из базы данных
в) повторно внесены в базу данных.
Мне это кажется очень плохим поведением. Все, что нужно для добавления строки, это… ну, добавить одну строку в базу данных! Операция добавления — буквально единственное, что я делаю со списком строк. Это не масштабируется, когда у нас есть 10 000 элементов в списке.
Кто-нибудь знает, как придать этой саге более вменяемое поведение производительности?
Кстати - вот как отображается IList, если вам это нужно -
HasMany(x => x.Rows)
.Table("OwnerHistorySagaRow")
.KeyColumn("CorrelationId")
.Element("Row")
.Cascade.AllDeleteOrphan();
Спасибо!