#c# #entity-framework
#c# #entity-framework
Вопрос:
Я вычисляю значение столбца из другого столбца, и мне нужно создать некластеризованный индекс для вычисляемого столбца.
Когда я пытаюсь указать индекс для вычисляемого столбца с помощью Entity Framework, система выдает исключение
В Microsoft произошло исключение типа ‘System.Data.SqlClient.SQLException’.EntityFrameworkCore.Relational.dll, но не был обработан в пользовательском коде
Дополнительная информация: Отфильтрованный индекс ‘UK_ProdBarCode_BarCodeNumber’ не может быть создан в таблице ‘ProdBarCode’, поскольку столбец ‘BarCodeNumber’ в выражении фильтра является вычисляемым столбцом. Перепишите выражение фильтра так, чтобы оно не включало этот столбец.
prodbarcode.Property<long>(ProdBarCode =>
ProdBarCode.BarCodeNumber).HasComputedColumnSql("CAST(BarCode AS Bigint)");
prodbarcode.HasIndex(ProdBarCode =>
new { ProdBarCode.BarCodeNumber })
.HasName("UK_ProdBarCode_BarCodeNumber")
.IsUnique(true)
.ForSqlServerIsClustered(false);
Комментарии:
1. «К сожалению, начиная с SQL Server 2014, нет возможности создать отфильтрованный индекс, где фильтр находится в вычисляемом столбце (независимо от того, сохранен он или нет)». — Не удается создать отфильтрованный индекс для вычисляемого столбца
2. Да, невозможно создать отфильтрованный индекс для вычисляемого столбца, но, вероятно, уместен вопрос: почему EF пытается создать отфильтрованный индекс? Я не вижу в этом определении ничего, что включало бы фильтр, и создание уникального индекса для вычисляемого столбца в противном случае работает нормально (например,
CREATE TABLE #a(BarCode INT, BarCodeNumber AS CAST(BarCode AS BIGINT)); CREATE UNIQUE INDEX IX_#a_ProdBarCode ON #a(BarCodeNumber);
; добавитьWHERE BarCodeNumber IS NOT NULL
, чтобы получить ошибку).
Ответ №1:
Сегодня я столкнулся с этой проблемой. К сожалению, я не смог найти никакой информации об этом в Entity Framework или Microsoft. Тем не менее, я нашел обходной путь для моей ситуации.
Если вы добавите фильтр самостоятельно и настроите исходный столбец или колонки, он должен достичь того же эффекта, и это допустимый SQL. Смотрите обновленный код ниже…
prodbarcode.Property<long>(ProdBarCode =>
ProdBarCode.BarCodeNumber)
.HasComputedColumnSql("CAST(BarCode AS Bigint)");
prodbarcode.HasIndex(ProdBarCode =>
new { ProdBarCode.BarCodeNumber })
.HasName("UK_ProdBarCode_BarCodeNumber")
.IsUnique(true)
.HasFilter($"{nameof(ProdBarCode.BarCode)} IS NOT NULL") // <-- filter on source field
.ForSqlServerIsClustered(false);