Хороший способ выбрать несколько строк с нескалярным списком ключей, используя Entity Framework 4 - PullRequest
3 голосов
/ 02 сентября 2011

Я использую EF 4 и пытаюсь найти хороший способ выбрать записи, в которых первичный ключ использует несколько столбцов, и использовать список объектов для поиска.Вот что я попробовал безуспешно:

У меня есть список объектов типа Foo.Foo имеет два свойства, A и B. Первичный ключ в таблице Order - это столбцы A и B.

var orders = (from o in context.Orders
              where FooList.Contains(new Foo { A = o.A, B = o.B }
              select o);

Это выдает ошибку, что я могу использовать только скалярное значение.Из того, что я могу сказать, мне нужен FooList, чтобы быть списком скаляров.Я также пытался соединиться со своим списком объектов, но это тоже не сработало:

var orders = (from o in context.Orders
              join foo in FooList
              on new { foo.A, foo.B } equals new { o.A, o.B }
              select o)

Очевидно, я мог бы просто перебрать все значения в FooList, получить нужный мне порядок иобновите его, но это очень медленно в моей текущей ситуации (около 6000 значений в FooList).

Есть идеи?

Ответы [ 3 ]

1 голос
/ 02 сентября 2011

Вы по-прежнему сможете использовать (вариант включен) обходной путь BuildContainsExpression , который был необходим до EF 4.

Результирующий SQL будет таким же.

0 голосов
/ 16 сентября 2011

Мы должны быть в состоянии сделать это, изменив дерево выражений. По сути, мы хотим перевести дерево выражений в sql следующим образом:

Where
(
   (Foo.A == "A" && foo.B == 1)
|| (Foo.A == "B" && foo.B == 2)
)

Так что, если мы используем синтаксис Contains и под обложками используем выражение visitor, чтобы пройти по дереву и заменить выражение, мы должны получить то, что хотим.

К сожалению, у меня недостаточно глубоких знаний о деревьях выражений LINQ, чтобы быстро найти решение.

Большинство примеров, которые я видел, имеют дело исключительно с модификацией дерева выражений для работы со скалярными значениями (List.Contains) или использованием дерева выражений для генерации собственного SQL для массового выполнения операций.

0 голосов
/ 02 сентября 2011

Возможно, вам придется «скарифицировать» ваш составной ключ в запросе, чтобы сопоставить ключ с уникальным скаляром.Например: скажем, ваши свойства A и B были строками:

var orders = (from o in context.Orders
              where FooList.Select(f => f.A + ";" + f.B)
                  .Contains(o.A + ";" + o.B)
              select o);

(Конечно, этот скаляр, как правило, не гарантированно уникален, но, возможно, все еще будет хорошо, если вы знаете, чтоваши строки A и B никогда не могут содержать точку с запятой.) Необходимо позаботиться о том, чтобы выражение в Contains можно было преобразовать в SQL (что будет работать в этом примере объединения строк).

...