Оптимизация / более быстрый выбор, чем «не все» в LINQ - PullRequest
1 голос
/ 30 мая 2019

Я использую EF 6 и .NET Framework 4.6.1.У меня есть сценарий, в котором мне нужно исключить родительскую запись, если все ее дочерние записи удовлетворяют определенному условию.

Это общая версия того, что я сделал до сих пор:

public ParentRecords GetParentRecordsExceptWhereSpecificStringOnAllChildren(string aSpecificString){ 
        return ParentRecords
            .Where(parent => !parent.ChildRecords
                .Select(child => child.SomeStringProperty)
                .All(c => c.Equals(aSpecificString))
        );
    }

Это занимает немного больше времени (в масштабе одной секунды на дочернюю запись), и сгенерированный SQL из EF содержит n-1 UNION ALL операторов, где n - количество дочерних записей.

Я подозреваю, что мне не хватает очевидного способа написания этого, который значительно улучшил бы производительность, но я этого не вижу (но я не мастер LINQ / EF в любом случае).

Я написал хранимую процедуру, которая возвращает те же данные, но гораздо быстрее, и не совсем в том же макете (одна плоская строка против строки для каждой дочерней записи).Однако мы стараемся избегать хранимых процедур, поэтому я возвращаюсь к точильному камню, выясняющему, как сделать этот LINQ быстрее.

Любые предложения будут с благодарностью.Если я не объяснил это ясно, пожалуйста, дайте мне знать.Я попытался сделать его общим для повторного использования, на случай, если кто-то еще окажется в такой ситуации.

1 Ответ

0 голосов
/ 31 мая 2019

Вы можете удалить выбор SomeStringProperty из вашего кода.

Использование любого

        ParentRecords.Where(parent =>
            parent.ChildRecords.Any(child => !child.SomeStringProperty.Equals(aSpecificString)));

Использование всех

       ParentRecords.Where(parent =>
            !parent.ChildRecords.All(child => child.SomeStringProperty.Equals(aSpecificString)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...