Я работаю над проектом ASP. Net Core MVC, в котором мы используем сетку MVC6 (https://mvc6-grid.azurewebsites.net/), чтобы показать некоторые сетки. Чтобы наилучшим образом использовать сетку, мы используем SQL представлений и передаем их напрямую через Queryables в Entity Framework, поэтому мы можем позволить сетке фильтровать все на SQL напрямую.
Все работает хорошо, но для одного просмотра нам нужно объединить данные из другой базы данных. Из того, что я прочитал, лучший способ сделать это - через OpenQuery, так как я получаю только выбранные поля. Таким образом, объединение в представлении выглядит следующим образом:
SELECT Stuff
FROM dbo.Licenses lic
LEFT OUTER JOIN
(
SELECT * FROM OPENQUERY([Server],'SELECT identUser.UserName, identUser.id FROM [Database].dbo.IdentityUsers identUser')
) AS identUser on identUser.id = lic.OwnerId
Выбор данных в представлении выполняется не слишком быстро, но он работает. К сожалению, у нас также есть глобальный поиск в сетке, который ищет все доступные поля в представлении. Эта функция напрямую не поддерживается сеткой MVC6, поэтому я использую шаблон репозитория для подготовки Queryable. Код C# выглядит следующим образом
public IQueryable<LicenseOverviewGridItem> QueryOverview(string searchTerm)
{
if (string.IsNullOrEmpty(searchTerm))
{
return _adminDbContext.LicenseOverviewGridItems;
}
return _adminDbContext.LicenseOverviewGridItems
.Where(
f =>
f.ActivationDateDescription.Contains(searchTerm) ||
f.ExpiryDateDescription.Contains(searchTerm) ||
f.LicenseDurationInDaysDescription.Contains(searchTerm) ||
f.LicenseName.Contains(searchTerm) ||
f.OrganizationName.Contains(searchTerm) ||
f.ProductName.Contains(searchTerm) ||
f.StateDescription.Contains(searchTerm) ||
f.TypeDescription.Contains(searchTerm) ||
f.UserName.Contains(searchTerm) ||
f.RightsOfUseDescription.Contains(searchTerm)
);
}
Теперь эта комбинация становится проблемной c, поскольку сетка MVC6 создает следующий запрос:
exec sp_executesql N'SELECT [l].[ActivationDate], [l].[ActivationDateDescription], [l].[ExpiryDate], [l].[ExpiryDateDescription], [l].[LicenseDurationInDays], [l].[LicenseDurationInDaysDescription], [l].[LicenseId], [l].[LicenseName], [l].[OrganizationName], [l].[ProductName], [l].[RightsOfUse], [l].[RightsOfUseDescription], [l].[StateDescription], [l].[TypeDescription], [l].[UserName]
FROM [LicenseOverviewGridItems] AS [l]
WHERE (((((((((((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[ActivationDateDescription]) > 0)) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[ExpiryDateDescription]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[LicenseDurationInDaysDescription]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[LicenseName]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[OrganizationName]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[ProductName]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[StateDescription]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[TypeDescription]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[UserName]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[RightsOfUseDescription]) > 0))
ORDER BY (SELECT 1)
OFFSET 0 ROWS FETCH NEXT @__p_1 ROWS ONLY',N'@__searchTerm_0 nvarchar(4000),@__p_1 int',@__searchTerm_0=N'delaquis',@__p_1=5
Проверка проблемы , комбинация
OFFSET 0 ROWS FETCH NEXT @__ p_1 ROWS ONLY
и
CHARINDEX (@__ searchTerm_0, [l]. [UserName])> 0
Причина и бесконечность l oop. Если я удаляю какую-либо часть, она работает нормально.
На целевом сервере я также создал индекс для identUser.UserName, identUser.id, но без помощи. Также я не смогу использовать индексированное представление. , поскольку SCHEMABINDING не поддерживается для выбора нескольких баз данных.
У меня заканчиваются варианты, что я могу сделать. Я мог бы переделать весь Queryying и обработать его вручную, но это, очевидно, довольно много изменений. Возможно ли при этом улучшение производительности?