Если x
вызывается так
foo, bar = x (foo)
return None
приведет к
TypeError: объект «NoneType» не является итерируемым
, если «bar»
не в foo
.
Пример
def x (foo): если «bar» в foo: return (foo, 'bar'), return no foo, bar = x (["foo", "bar", "baz"]) print foo, bar foo, bar = x (["foo", "NOT THERE", "baz"]) print foo, bar
В результате:
['foo', 'bar', 'baz'] bar Traceback (последний последний вызов): Файл " f.py ", строка 9, в & lt; module & gt; foo, bar = x (["foo", "NOT THERE", "baz"]) TypeError: объект «NoneType» не итерируется
Причина, по которой это происходит, является тонкой.
Queryable.All
необходимо вызвать с помощью Expression
. Передача только методом 'reference' создает делегат, а впоследствии Enumerable.All
становится кандидатом вместо предполагаемого Queryable.All
.
Вот почему ваше решение, которое вы отправили в качестве ответа, работает правильно.
EDIT
, поэтому, если вы напишете инструкцию как это, она будет работать без исключения:
var res = ctx.As.Where(
a => a.Bs.Select(b => b.SomeName).All(b => names.Contains(b)));
Семантика вашего запроса выглядит хорошо для меня; Очевидно, что получение внутренней ошибки поставщика не является предполагаемым поведением! Я ожидал бы более явного представления о том, что EF не сможет перевести ваш запрос в операцию хранилища, если это на самом деле проблема.
Другой способ сделать то, что вы хотите, будет:
var names = new[] {"Name1", "Name2"};
var nameCount = names.Length;
var ctx = new DatabaseContext("EFPlayingEntities");
var result = ctx.As
.Where(a => a.Bs
.Select(b => b.SomeName)
.Intersect(names)
.Count() == a.Bs.Count());
(получить каждый A
такой, что пересечение его B
s 'имен с фиксированным списком дает все B
s)
, хотя я не пробовал это чтобы убедиться, что EF может успешно выполнить этот .
Другой способ:
var names = new[] {"Name1", "Name2"};
var ctx = new DatabaseContext("EFPlayingEntities");
var result = ctx.As
.Where(a => !a.Bs.Select(b => b.SomeName).Except(names).Any());
(получить каждый A
, чтобы список его B
s 'имена сводятся к нулю, вынимая фиксированный список)
также не проверен.
Except
, безусловно, лучше, чем сейчас. И да, все: ваш оригинал, ваш ответ и мои два пути, все имеют одинаковую семантику - выбор - это просто вопрос вкуса и, конечно же, может ли EF успешно перевести ...
– AakashM
1 March 2012 в 16:27
Я разработал решение для этого, если кто-то заинтересован. Выполнение следующего эквивалентно и не приводит к исключению в вопросе:
var res = ctx
.Bs
.GroupBy(b => b.A)
.Where(g => g.All(b => names.Contains(b.SomeName)))
.Select(g => g.Key);
Я не знаю, является ли это лучшим способом, хотя!?