Как использовать один запрос, чтобы проверить, существует ли значение в двух таблицах - PullRequest
1 голос
/ 20 июня 2019

Используя EF Core 2.2.2, у меня есть два простых запроса с целью определить, используется ли Color в таблице CollectionItem или PuzzleColor:

var isACollectionItem = _applicationDbContext.CollectionItem.Any(collectionItem => collectionItem.ColorId == color.Id);
var isAPuzzleItem = _applicationDbContext.PuzzleColor.Any(puzzleColor => puzzleColor.ColorId == color.Id);
var eitherOr = 
        _applicationDbContext.CollectionItem.Any(collectionItem => collectionItem.ColorId == color.Id)
    ||  _applicationDbContext.PuzzleColor.Any(puzzleColor => puzzleColor.ColorId == color.Id);

Первые две строки генерируют два отдельных запроса, которые выглядят следующим образом:

SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [CollectionItem] AS [collectionItem]
        WHERE [collectionItem].[ColorId] = @__color_Id_0)
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END

Объединение их с помощью оператора || означает, что он будет запускаться как в случае, если первый не соответствует действительности, в противном случае он будет выполняться толькопервый запрос.

Можно ли объединить обе проверки в один запрос с EF?

1 Ответ

1 голос
/ 20 июня 2019

Мне удалось получить один запрос, используя в качестве отправной точки таблицу Color (которую я не включил в исходное сообщение, мой плохой):

bool singleQuery = _applicationDbContext.Color
    .Any(myColor =>
            myColor.Id == _applicationDbContext.CollectionItem.FirstOrDefault(collectionItem => collectionItem.ColorId == color.Id).ColorId
        ||  myColor.Id == _applicationDbContext.PuzzleColor.FirstOrDefault(puzzleColor => puzzleColor.ColorId == color.Id).ColorId);

Что переводится на:

SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [Color] AS [myColor]
        WHERE ([myColor].[Id] = (
            SELECT TOP(1) [collectionItem].[ColorId]
            FROM [CollectionItem] AS [collectionItem]
            WHERE [collectionItem].[ColorId] = @__color_Id_0
        )) OR ([myColor].[Id] = (
            SELECT TOP(1) [puzzleColor].[ColorId]
            FROM [ServedColor] AS [puzzleColor]
            WHERE ([puzzleColor].[Discriminator] = N'PuzzleColor') AND ([puzzleColor].[ColorId] = @__color_Id_1)
        )))
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END

Я полагаю, что более производительный запрос может быть создан с использованием соединений или объединений, хотя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...