Я нашел ответ от «Ладислав Мрнка» точным и отметил его как принятый.Вот другие обходные пути, которые я нашел, пытаясь найти какое-то решение.Однако решение, которое я искал, в общем случае невозможно.
Одна из возможностей - установить StoreGeneratedPattern = Computed
, чтобы EF знал, что это значение рассчитывается.А затем создайте хранимую процедуру, чтобы фактически изменить значение SortIndex
.Обычно это приводит к изменению значений в двух строках (их замене), чтобы изменить порядок сортировки.Эта процедура вместе с триггером на INSERT
дает гарантию, что данные остаются согласованными в БД.Невозможно создать новую строку без надлежащего значения, установленного в SortIndex
, невозможно сделать так, чтобы два объекта имели одно и то же значение (если только хранимая процедура не содержит ошибку), и невозможно каким-либо образом вручную разбить значение, поскольку это невозможноредактировать через EF.Выглядит как отличное решение.
Можно легко сопоставить хранимые процедуры с функциями в EF.
Проблема в том, что теперь можно ввести новую строку, и EF правильно обновляет данные в своемкеш, но кеш не обновляется после вызова хранимой процедуры.Тем не менее, требуется какое-то ручное обновление или функция обновления.В противном случае следующий вызов для получения объектов, отсортированных по SortIndex
, даст неправильные результаты.
Кроме этого, можно установить MergeOption = MergeOption.OverwriteChanges
для нескольких объектов, что заставляет EF несколько лучше обновлять данные из БД.После этого можно перечитать объект после его вставки или вызова хранимой процедуры, и он будет обновлен.Однако чтение коллекции объектов с помощью db.Section.OrderBy(o => o.SortIndex)
будет по-прежнему возвращать кэшированные результаты с неправильным порядком сортировки.
Если кому-то это интересно, можно установить MergeOption
по умолчанию для чего-то другого, добавив частичный класс EF, а затемчастичный метод OnContextCreated
, как здесь:
public partial class DatabaseEntities
{
partial void OnContextCreated()
{
Subsection.MergeOption = MergeOption.OverwriteChanges;
Section.MergeOption = MergeOption.OverwriteChanges;
Function.MergeOption = MergeOption.OverwriteChanges;
}
}