Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Страсти по делегатам

3561  1 2 3 4 все
AlexNek патриот25.03.24 19:58
AlexNek
NEW 25.03.24 19:58 
в ответ Срыв покровов 25.03.24 14:18

Только теперь дошло, что хотелось и таблицу засунуть в выражение смущ

#21 
Срыв покровов патриот26.03.24 06:40
NEW 26.03.24 06:40 
в ответ AlexNek 25.03.24 19:58

а теперь модифицируем задачу:

Нужно получить людей, которые не участвовали ни в одном ивенте. Как должен выглядеть предикат?

#22 
AlexNek патриот26.03.24 10:35
AlexNek
NEW 26.03.24 10:35 
в ответ Срыв покровов 26.03.24 06:40

видимо срочно надо... может чем то поможет.

Обычно можно сделать так

var personsNotInEvent = dbContext.Persons
    .Where(p => !dbContext.Events.Any(e => e.PersonId == p.PersonId))
        .ToList();
#23 
alex445 коренной житель26.03.24 11:31
NEW 26.03.24 11:31 
в ответ AlexNek 26.03.24 10:35

Это то, что я выше предлагал. Только у вас подзапрос будет выполняться на каждое вхождение основного запроса (саечка за неоптимальность улыб).

#24 
Срыв покровов патриот26.03.24 11:38
NEW 26.03.24 11:38 
в ответ alex445 26.03.24 11:31
Только у вас подзапрос будет выполняться на каждое вхождение основного запроса (саечка за неоптимальность улыб)

нука расскажи, почему ты так решил?

Это то, что я выше предлагал.

ничего дельного ты тут не предложил

#25 
Срыв покровов патриот26.03.24 11:41
NEW 26.03.24 11:41 
в ответ AlexNek 26.03.24 10:35
Обычно можно сделать так

это правильный ответ
но чтобы сохранить интригу, что изменится от того, если ЛИНК написать так(как у нас внегласно заведено)?

вместо ! напишем == false

var personsNotInEvent = dbContext.Persons
    .Where(p => dbContext.Events.Any(e => e.PersonId == p.PersonId) == false)
        .ToList();
#26 
alex445 коренной житель26.03.24 13:39
NEW 26.03.24 13:39 
в ответ Срыв покровов 26.03.24 11:38, Последний раз изменено 26.03.24 13:41 (alex445)
Только у вас подзапрос будет выполняться на каждое вхождение основного запроса (саечка за неоптимальность улыб)
нука расскажи, почему ты так решил?

потому что делегат в where выполняется для каждого вхождения

#27 
alex445 коренной житель26.03.24 13:43
NEW 26.03.24 13:43 
в ответ Срыв покровов 26.03.24 11:41
var personsNotInEvent = dbContext.Persons
    .Where(p => dbContext.Events.Any(e => e.PersonId == p.PersonId) == false)
        .ToList();

Вы начитались "каверзных вопросов", где требуют знать все тонкости, как построитель и оптимизатор запросов внутри преобразует те или иные условия в фильтрующих делегатах?

#28 
Срыв покровов патриот26.03.24 14:06
NEW 26.03.24 14:06 
в ответ alex445 26.03.24 13:39
потому что делегат в where выполняется для каждого вхождения

бред какой
весь этот LINQ конвертируется в один SQL-запрос

#29 
Срыв покровов патриот26.03.24 14:07
NEW 26.03.24 14:07 
в ответ alex445 26.03.24 13:43
Вы начитались "каверзных вопросов", где требуют знать все тонкости, как построитель и оптимизатор запросов внутри преобразует те или иные условия в фильтрующих делегатах?

нет, я заметил, что один запрос как-то очень медленно обрабатывается

#30 
alex445 коренной житель26.03.24 14:24
NEW 26.03.24 14:24 
в ответ Срыв покровов 26.03.24 14:06
весь этот LINQ конвертируется в один SQL-запрос

А если я использую в


dbContext.Events.Any(e => e.PersonId == p.PersonId)


какую-нибудь внешнюю по отношению к запросу коллекцию, типа


myCollection.Contains(item => item.PersonId == p.PersonId)


то вся коллекция myCollection будет передана в запрос?

#31 
AlexNek патриот26.03.24 17:33
AlexNek
NEW 26.03.24 17:33 
в ответ Срыв покровов 26.03.24 11:41

Linqpad даёт следующее


List<LiveResult> (2 items)•••
Case ResultsGraph Mean Min Max Range AllocatedBytesΞΞ OperationsΞΞ Phase
BenchmarkDemoWhereNot 2.72 μs 2.67 μs 2.75 μs 3% 2'200 3'145'728 Complete
BenchmarkDemoWhereFalse 2.79 μs 2.70 μs 2.98 μs 10% 2'240 7'077'888 Complete
#32 
AlexNek патриот26.03.24 17:39
AlexNek
NEW 26.03.24 17:39 
в ответ alex445 26.03.24 11:31
Это то, что я выше предлагал.

А можно оптимальный код повторить? смущ

Желательно чтобы можно было засунуть в Linqpad или netfiddle или на крайняк готовый проект для студии.

#33 
Срыв покровов патриот26.03.24 18:37
NEW 26.03.24 18:37 
в ответ alex445 26.03.24 14:24
какую-нибудь внешнюю по отношению к запросу коллекцию, типа


myCollection.Contains(item => item.PersonId == p.PersonId)


то вся коллекция myCollection будет передана в запрос?

Это имхо вообще не переведётся в SQL.
А вот если у тебя будет коллекция простых integer, то да, все значения передадутся в запрос.


А ты как думал: на каждый элемент по запросу в БД?))

#34 
Срыв покровов патриот26.03.24 18:38
NEW 26.03.24 18:38 
в ответ AlexNek 26.03.24 17:33

твои бенчмарки в базу данных лезут или в памяти работают?

#35 
AlexNek патриот26.03.24 19:20
AlexNek
NEW 26.03.24 19:20 
в ответ Срыв покровов 26.03.24 18:38

Там локальная SQLite, хотя обновил до нет 8.0

Немного изменил под существующие таблицы

#load "BenchmarkDotNet"

void Main()
{

}

[Benchmark]
public void BenchmarkDemoWhereNot() 
{
    var context = this;
    
    var personsNotInEvent = context.Artists
                    .Where (p => !Albums.Any(e => e.ArtistId == p.ArtistId));
}

[Benchmark]
public void BenchmarkDemoWhereFalse()
{
    var context = this;
    
    var personsNotInEvent = context.Artists
                    .Where (p => Albums.Any(e => e.ArtistId == p.ArtistId) == false);
}
#36 
alex445 коренной житель26.03.24 22:39
NEW 26.03.24 22:39 
в ответ Срыв покровов 26.03.24 18:37
А ты как думал: на каждый элемент по запросу в БД?))

А я не помню, как оно работает. Вроде, если сущности из одного контекста, то он пытается это в один запрос сделать. Но в моём примере по ссылке либо джойны придлагают, либо сначала сделать один запрос, превратить его в просто коллекцию объектов, а потом второй запрос с использованием этой коллекции.

#37 
Срыв покровов патриот26.03.24 23:21
NEW 26.03.24 23:21 
в ответ alex445 26.03.24 22:39

Я-то думал, ты в ЕФ шаришь
А ты теоретик.

#38 
Срыв покровов патриот26.03.24 23:24
26.03.24 23:24 
в ответ AlexNek 26.03.24 19:20

ну и как, есть разница в скорости в SQL Lite?

И интересно было бы посмотреть сгенерированный SQL.
Я не исключаю, что моя проблема существует только при работе с ораклом.

#39 
AlexNek патриот26.03.24 23:36
AlexNek
NEW 26.03.24 23:36 
в ответ Срыв покровов 26.03.24 23:24
И интересно было бы посмотреть сгенерированный SQL.

но проблемо, для этого linqpad и открывался

SELECT "a"."ArtistId", "a"."Name"
FROM "Artist" AS "a"
WHERE NOT EXISTS (
    SELECT 1
    FROM "Album" AS "a0"
    WHERE "a0"."ArtistId" = "a"."ArtistId")


ну и как, есть разница в скорости в SQL Lite?

на такой мелочевке данных то.


Отчего - это нужно изучать специально. Может и нет 8.0 починили

#40 
1 2 3 4 все