Entity Framework - проблема проекции LinQ - PullRequest
1 голос
/ 10 декабря 2010

Я хочу создать объект Entity из оператора LinQ, но не хочу загружать все его столбцы.

В моем объекте ORDERS много столбцов, но я просто хочу получить ссылкуи столбцы OPERATION, так что оператор SQL и результат будут меньше.

Этот оператор LinQ работает правильно и загружает все атрибуты моего объекта:

var orders = (from order in context.ORDERS
             select order);

Однако следующий оператор не может загрузить только два свойствамоего объекта

 var orders = (from order in context.ORDERS
               select new ORDERS
               {
                    REFERENCE = order.REFERENCE,
                    OPERATION = order.OPERATION
               });

Сгенерирована ошибка:

Сущность или сложный тип ModelContextName.ORDERS нельзя создать в запросе LINQ to Entities.

В чем проблема?Разве нельзя частично загрузить объект таким образом?

Заранее благодарю за ответы.


ОТВЕТ

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

var orders = (from order in context.ORDERS
              select new
              {
                  REFERENCE = order.REFERENCE,
                  OPERATION = order.OPERATION, 
              })
              .AsEnumerable()
              .Select(o =>
                        (ORDERS)new ORDERS
                        {
                            REFERENCE = o.REFERENCE,
                            OPERATION = o.OPERATION
                        }
        ).ToList().AsQueryable();

И я получаю именно то, что хочу, оператор SQL не идеален, но он возвращает только те 2 столбца, которые мне нужны (и другойстолбец, который содержит для каждой строки «1», но я не знаю, почему на данный момент) - я также попытался построить подобъекты с помощью этого метода, и он работает хорошо.

Ответы [ 3 ]

2 голосов
/ 21 апреля 2011

Проблема с вышеприведенным решением состоит в том, что с момента вызова AsEnumerable () запрос будет выполняться в базе данных.В большинстве случаев это будет хорошо.Но если вы работаете с большой базой данных, выборка всей таблицы (или представления), вероятно, не то, что вам нужно.Итак, если мы удалим AsEnumerable, мы вернемся к квадрату 1 со следующей ошибкой:

Сущность или сложный тип ModelContextName.ORDERS не могут быть созданы в запросе LINQ to Entities.

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

public sealed class ProjectedORDERS : ORDERS {}

Спроецированный запрос (с использованием функции ковариации):

IQueryable<ORDERS> orders = (from order in context.ORDERS
              select new ProjectedORDERS
              {
                  REFERENCE = order.REFERENCE,
                  OPERATION = order.OPERATION, 
              });

Вуаля!Теперь у вас есть спроецированный запрос, который будет сопоставлен с сущностью и будет выполняться только тогда, когда вы захотите.

2 голосов
/ 10 декабря 2010

Нет, вы не можете проецировать на сопоставленный объект. Вместо этого вы можете использовать анонимный тип:

var orders = (from order in context.ORDERS
              select new
              {
                  REFERENCE = order.REFERENCE,
                  OPERATION = order.OPERATION
              });
0 голосов
/ 10 декабря 2010

Я думаю, что проблема заключается в создании новых сущностей в самом запросе, так как насчет попытки это сделать:

context.ORDERS.ToList().Select(o => new ORDERS
{
    REFERENCE = o.REFERENCE,
    OPERATION = o.OPERATION
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...