Честно говоря, я думаю, что это, вероятно, связано не столько с вашим кодом, сколько с проблемами сети или базы данных. Хотя есть способы улучшить этот код, на самом деле нет причин, по которым он не должен работать согласованно, как есть.
Тем не менее, вы блокируете все эти запросы, что никогда не было хорошей идеей. Все, что делает EF Core - asyn c. Методы syn c просто блокируют асинхронные c методы и существуют только для сценария ios, где невозможно использовать asyn c, например, делегаты событий в настольных приложениях и тому подобное. Короче говоря, вы должны всегда использовать асин c методы, если только вы не попадаете в конкретную c ситуацию, когда вы не можете. В приложении ASP. NET Core такой ситуации нет, поэтому всегда следует использовать asyn c. Длинные и короткие, используйте ToListAsync
вместо ToList
и await
в каждой строке.
Далее, нет смысла в ваших предложениях where. Независимо от того, выбираете ли вы много только для предметов, у которых есть собаки, например, или для всех предметов, независимо от того, есть у них собаки или нет, вы все равно получите те же результаты. В любом случае все это будет выполняться в базе данных, поэтому ни один подход, ни другой не принесут никакой пользы в производительности. Вам также не нужно использовать Include
, если вы выбираете из отношений. EF достаточно умен, чтобы выдавать объединения на основе данных, которые он должен вернуть.
var query1 = await context.Playarea
.SelectMany(x => x.Cats.Select(y => new MyClass(x.Id, y.Name, y.Age))).ToListAsync();
Существует также проблема ваших двух собачьих запросов. Одинаковые результаты будут возвращены для обоих запросов. Единственное отличие состоит в том, что один набор будет иметь y.Name
, а другой набор будет иметь y.Leads.Name
в качестве значения Name
. Акт включения Leads
не каким-то образом отфильтровывает результат, который не имеет Leads
, и, конечно, первый запрос вообще не фильтруется, так или иначе. Я бы подумал, что вместо этого вам понадобится что-то вроде следующего:
var query3 = await context.Playarea
.SelectMany(x => x.Dogs, (x, y) => new MyClass(x.Id, y.Leads is null ? y.Name : y.Leads.Name, y.Age)).ToListAsync();
Другими словами, Leads.Name
будет использоваться, если связь существует, и в противном случае она вернется к Name
.