Linq to Entities в EF4 с использованием сгенерированных классов POCO - PullRequest
3 голосов
/ 22 декабря 2010

Я использовал надстройку ADO.NET C # POCO Entity Generator для Visual Studio для генерации классов POCO для моих сущностей.

Когда я пытаюсь использовать класс в запросе Linq to Entities, например, приведенном ниже:

var q = from w in entities.Widgets
        select new Widget
        {
            Id = w.Id,
            WidgetName = w.WidgetName,
            WidgetDescription = w.WidgetDescription
        };


return q.ToList();

Я получаю следующее исключение:

«Сущность или сложный тип MyNamespace.Widget 'нельзя создать в запросе LINQ to Entities».

Единственный способ обойти это - использовать анонимный тип, а затем другой запрос LINQ:

var q = from w in entities.Widgets
        select new
        {
            Id = w.Id,
            WidgetName = w.WidgetName,
            WidgetDescription = w.WidgetDescription
        };

var r = from e in q.AsEnumerable()
        select new Widget
        {
            Id = e.Id,
            WidgetName = e.WidgetName,
            WidgetDescription = e.WidgetDescription
        };

return r.ToList();

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

Тот факт, что классы POCO генерируются ADO.NET C # POCO Entity Generator, похоже, не связан с этой проблемой; Я попытался использовать свои собственные классы POCO и увидел то же исключение.

Большое спасибо.

EDIT: Добавлена ​​ссылка на пошаговое руководство по использованию надстройки ADO.NET C # POCO Entity Generator для Visual Studio - http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx

Ответы [ 2 ]

4 голосов
/ 22 декабря 2010

Полагаю, MyNamespace.Widget - это пользовательский класс, а не часть EDM?

Если это так, вы не можете проецировать запрос LINQ-Entities в пользовательский тип.Не имеет значения, используете ли вы POCO или нет.

У вас есть правильная идея проецирования на анонимный тип.

Вы можете сформировать запрос на клиенте, когда у вас есть материализованный запрос на сервере:

var widgets = entities
               .Widgets
               .ToList() // materialize query
               .Select(x => new Widget
                       {
                          Id = w.Id,
                          WidgetName = w.WidgetName,
                          WidgetDescription = w.WidgetDescription
                       }
               ).ToList();

Это немного приятнее, чем ваш обходной путь.

Но возникает вопрос - почему вы не возвращаете «Виджет»?типа на EDM в первую очередь?

Весь смысл POCO в том, что вы можете разделить логику персистентности на простые классы.Поэтому я не уверен, почему вы проецируете из простого типа (POCO) в другой (на вид идентичный) простой тип.Вы сопоставляете свои POCO с DTO для N-уровневого транспорта?

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

Эта страница предполагает, что это происходит потому, что вы создаете объект Entity вне области Entity Framework, что, по-видимому, недопустимо. По сути, они используют тот же обходной путь, что и вы, дважды выбирая результат из анонимного типа после первоначального выбора.

Если бы это был я, я бы, вероятно, избежал всего этого, просто выбрав w и покончив с этим, или создав новый специальный класс типа View, приспособленный для специализации Widget. Надеюсь, есть лучший ответ, чем этот:)

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