Выражение LINQ вызывает «Внутренняя ошибка поставщика данных .NET Framework 1025.» [duplicate]

Если 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» не итерируется  
5
задан kmp 1 March 2012 в 11:17
поделиться

3 ответа

Причина, по которой это происходит, является тонкой.

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)));
8
ответ дан leppie 15 August 2018 в 20:00
поделиться
  • 1
    Ого! Поэтому, несмотря на то, что .All (b = & gt; names.Contains (b)) функционально (я имею в виду то, что он делает, а не как он это делает), эквивалентный .All (names.Contains), что вы говорите, является основной механизм отличается, и я попал в ошибку в EF, когда он оценивает дерево выражений? Я просто попробовал это и это «ctx.As.Where» (a = & gt; a.Bs.Select (b = & gt; b.SomeName) .Все (b = & gt; names.Contains (b))) & quot; на самом деле выполняется без ошибок! Спасибо! – kmp 1 March 2012 в 16:47
  • 2
    Надеюсь, вы не возражаете, я добавил немного вашего ответа, чтобы, если кто-нибудь еще встретит это, они сразу увидят предложенное вами изменение. – kmp 1 March 2012 в 16:51
  • 3
    @ user1039947: Нет проблем :) Это не ошибка EF, а недостающая функция с компилятором выражений C #. – leppie 1 March 2012 в 18:43
  • 4
    Я просто поставил щедрость на подобный вопрос ... хочу схватить его? – Shaul Behr 13 December 2012 в 15:29

Семантика вашего запроса выглядит хорошо для меня; Очевидно, что получение внутренней ошибки поставщика не является предполагаемым поведением! Я ожидал бы более явного представления о том, что 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 'имена сводятся к нулю, вынимая фиксированный список)

также не проверен.

1
ответ дан AakashM 15 August 2018 в 20:00
поделиться
  • 1
    Благодарим вас за ответ и оба выполняйте штраф без исключения! Тем не менее, ни одно из ваших решений не соответствует функциональности, так как мне нужно, чтобы он также возвращал любой A, в котором есть коллекция Bs с подмножеством коллекции имен, которые я передаю. В моих примерах данных я ожидал бы, что A2 также будет возвращен с тех пор он имеет "Name1" внутри него. – kmp 1 March 2012 в 15:36
  • 2
    Кстати, если вы создаете поддельный «Контекст», класс, где коллекция As представляет собой List & lt; A & gt; и тогда запрос, который у меня есть в вопросе, отлично работает и возвращает то, что я ожидаю. Я придумал способ сделать эквивалентную функциональность (см. Мой ответ), которая работает, но я не уверен, что это лучший способ (это может быть единственный способ, как это кажется ошибкой в ​​Entity Framework для меня). – kmp 1 March 2012 в 15:53
  • 3
    @user oops, имел подмножество неправильного пути; обновил мой ответ. Я думаю, что путь 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);

Я не знаю, является ли это лучшим способом, хотя!?

2
ответ дан kmp 15 August 2018 в 20:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: