Entity Framework Query - получение объектов в определенном порядке - PullRequest
7 голосов
/ 04 мая 2011

У меня есть список, в котором указаны идентификаторы ряда объектов в моей базе данных.Я хочу получить набор объектов, все из одной таблицы, которые имеют эти идентификаторы, и сохранить их в этом точном порядке, и я хочу, чтобы он выполнялся как один запрос к БД (а не 'N').

Например, у меня есть список идентификаторов {5, 3, 6, 9}, и я хочу получить список объектов Customer с этими идентификаторами и сохранить их в порядке {Customer (5, 'Bob'),Клиент (3, «JimBo»), Клиент (6, «Джо»), Клиент (9, «Джек»)}.

Объем данных достаточно мал, поэтому я не возражаю против-сортировать его после запроса БД.Я мог бы сделать все это примерно за 15 строк чистого кода (включая повторную сортировку вручную), но я чувствую, что должен быть одно- или двухстрочный запрос LINQ к EF, который должен делать это легко.

Ответы [ 4 ]

3 голосов
/ 04 мая 2011

Я не думаю, что все можно сделать за один запрос, но это легко сделать за два запроса.Один в БД и один в памяти.

Первый запрос выберет только клиентов с указанными идентификаторами:

var customers = (from c in context.Customers
                where itemIds.Contains(c.Id)
                select c).AsEnumerable();

Второй запросит их в соответствии с вашим списком:

var customers = from id in itemIds 
                join c in customers 
                on id equals c.Id
                select c;

var customersList = customers.ToList();
3 голосов
/ 04 мая 2011

Я считаю, что вам нужно будет выполнить заказ после получения результатов.Я бы, наверное, так решил.

var efQuery = /* your query here */.AsEnumerable(); // force evaluation 
var orderedResult = from id in idList // { 5, 3, 6, 9 }
                    join item in efQuery
                    on id equals item.Id
                    select item;

Объединение в памяти списка идентификаторов с результатом запроса сохранит порядок идентификаторов.

Редактировать: Из комментария

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

Я указываю на http://msdn.microsoft.com/en-us/library/bb534675.aspx, the Замечания раздел

Объединение сохраняет порядок элементов external, а для каждого из этих элементов порядок совпадающих элементов inner.

0 голосов
/ 04 мая 2011
void Main()
{
    List<Data> data = new List<Data>();
    data.Add(new Data{Id =1, Name = "ABC1"});
    data.Add(new Data{Id =2, Name = "ABC2"});
    data.Add(new Data{Id =3, Name = "ABC3"});
    data.Add(new Data{Id =4, Name = "ABC4"});
    data.Add(new Data{Id =5, Name = "ABC5"});

    var result = from d in data
                let ids = new List<int>{3,4,5}
                where ids.Any(i=> i == d.Id)
                select d;
    result.Dump();              
}

// Define other methods and classes here
class Data
{
    public int Id{get;set;}
    public string Name{get;set;}
}

Идентификаторы могут быть еще одним запросом, чтобы получить идентификаторы откуда-то еще, но заказывайте их как хотите.Обратите внимание, что это код Linqpad, следовательно, метод .Dump ().

0 голосов
/ 04 мая 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...