#c# #sql #entity-framework
#c# #sql #entity-framework
Вопрос:
У меня есть 4 несвязанных объекта, и я хотел бы запросить у них определенное ключевое слово. У каждого объекта было последнее измененное поле, и я хотел бы вернуть 50 лучших результатов поиска по 4 таблицам, упорядоченным по последнему измененному полю. Возможно ли это вообще?
В прошлом я использовал представление для выполнения подобных действий … но я не понимаю, как сначала добиться этого с помощью кода EF.
Ответ №1:
Вам нужно будет:
- Поиск в каждой таблице
- Преобразуйте результаты в общий тип
- Объединить результаты
- Сортировать / выбирать из этого объединенного списка
- Возьмите первые 50 результатов.
Первые два можно выполнить с помощью LINQ to Entities, а последние три — с помощью LINQ to Objects .
РЕДАКТИРОВАТЬ Этот подход будет выглядеть примерно так:
var resA = from a in db.A
where ConditionA(a)
select MakeSharedFromA(a);
var resB = from b in db.B
where ConditionB(b)
select MakeSharedFromB(b);
var resC = from c in db.C
where ConditionC(c)
select MakeSharedFromC(c);
var resD = from d in db.D
where ConditionD(d)
select MakeSharedFromD(d);
var merged = resA.AsEnumerable().Take(50)
.Concat(resB.AsEnumerable().Take(50))
.Concat(resC.AsEnumerable().Take(50))
.Concat(resD.AsEnumerable().Take(50));
var res = merged.Sort(x => x.SortField).Take(50);
Если каждый из MakeSharedFromX
методов может быть заменен на лямбда-выражение (для получения дерева выражений), которое ограничено операторами и функциями, которые поддерживает LINQ to Entities, то отбросьте AsEnumerable
Take
вызовы and с шага конкатенации, и все это может быть выполнено на стороне сервера.
Комментарии:
1. Это заставит меня выбрать не менее 50 записей из каждой таблицы. Есть ли способ поместить все это в LINQ to Entities (= LINQ to SQL)?
2. @KeesC.Bakker Только в том случае, если коллекции сущностей имеют один и тот же тип, в противном случае вы пытаетесь объединить яблоки и апельсины. Возможно, стоит попробовать с шагом проекции / преобразования в L2E, а затем посмотреть, поддерживает ли L2E
Concat
оператор. Я расширю A…3. Я создал для запросов (в них orderby и Take(50)). Каждый запрос выбирает запись в классе ResultRecord. Когда я делаю
var searches = from s in setA.Concat(setB).Concat(setC).Concat(setD) orderby s.Modified select s;
, все работает идеально! Не знаю о последствиях для производительности.4. Я бы, вероятно, согласился с вашей интуицией в отношении сохраненной процедуры или представления. Похоже, это та область, где KISS будет применяться, а не пытаться заставить EF делать что-то, в чем он не так хорош, и у большинства ORM в целом будут проблемы с тем, что вы пытаетесь сделать.
5. Это решение все еще действует для EF 6 или есть какой-нибудь лучший способ?