Linq-to-entity не работает точно так же, как SQL.Он выполняет левое соединение, только если ваш запрос позволяет это (у вас нет ручного управления этим поведением, если вы не пишете соединение вручную).Это не случай вашего запроса, потому что он использует x.TableBChildren.Any
= он требует, чтобы в родительской таблице была любая запись из дочерней таблицы, удовлетворяющая условию, поэтому он использует внутреннее соединение.
Я не пробовал и естьвозможно, лучший способ, но я думаю, что это может работать:
var query = (from x in myParentClasses.Include(x => x.TableBChildren)
where !x.TableBChildren.Any()
select x)
.Concat(
from x in myParentClasses.Include(x => x.TableBChildren)
where x.TableBChildren.Any(y => y.FieldA == 1 || y.Id == null)
select x)
.ToList();
Первая часть выбирает все записи, которые не имеют связанных сущностей, а вторая часть выбирает записи со связанными сущностями, удовлетворяющими вашему условию.Он объединяет эти две части.
Также помните, что Include
не будет фильтровать ваши отношения - он будет выбирать все из них каждый раз.Если вы хотите отфильтровать их, вы должны написать запрос с проекцией.
Редактировать:
Если вы хотите отфильтровать TableB
, вы не можете использовать обычный запрос и Include
.Вы также не можете вернуть экземпляры MyParentClass
.Вы должны использовать проекцию:
var query = from x in myParentClasses
select new
{
Id = x.Id,
// Rest of properties from myParentClass you want to receive
TableBChildren = x.TableBChildren.Where(y => y.FieldA == 1 || y.Id == null)
};
Это вернет анонимный тип с отфильтрованными TableB
с.Невозможно проецировать в сопоставленную сущность (MyParentClass
).