Установить расширенное свойство через Linq-to-entity - PullRequest
3 голосов
/ 24 января 2011

Я хочу получить данные и установить свойство, которое было добавлено к объекту Entity (через частичный класс) на лету.

Как я могу это сделать?

это мой запрос:

var ret = (from item in contex.Items
               select new Itemm
               {   
                  Title = item.Title,
                  Count = 1 // more complex: Count =item.refToAnotherEntity.Count()                                          
               });

public partial class Itemm 
{
     public int Count { get; set; }
}

Я получаю сообщение об ошибке: объект или сложный тип не могут быть созданы в запросе LINQ to Entities

Ответы [ 4 ]

0 голосов
/ 24 сентября 2012

Я пытаюсь достичь того же результата, что и вы.Моим лучшим решением до сих пор было создание Wrapper для моей сущности со свойством Count для установки дополнительного свойства в частичном классе.Если взять в качестве примера ваш случай, это будет выглядеть так:

public class ItemWithCount
{
   public Item Item { get; set; }
   public int Count
   {
        get { return Item.Count; }
        set { Item.Count = value; }
   }
}

Тогда вы можете сделать запрос следующим образом:

var ret = (from item in contex.Items
           select new ItemWithCount
           {   
              Item = item,
              Count = item.refToAnotherEntity.Count()                                          
           }).AsEnumerable().Select(x => x.Item);

Вместо создания оболочки вы можете выбрать анонимный тип с помощьюте же 2 свойства, но это означает, что после запроса вам нужно будет просмотреть результаты и установить значение свойства Count каждой сущности.Примерно так:

var ret = (from item in contex.Items
           select new
           {   
              Item = item,
              Count = item.refToAnotherEntity.Count()                                          
           });
Parallel.ForEach(ret, x => x.Item.Count = x.Count);
var results = ret.Select(x => x.Item);

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

0 голосов
/ 24 января 2011

Если вы хотите переместить обработку на клиентскую сторону (т.е. перейти от IQueryable<T> к IEnumerable<T>), то вы можете сделать что-то вроде этого:

var query = (from item in context.Items
    select new Item {                     
        Title = item.Title
    });

var ret = query.AsEnumerable().Select(i => {
    // Set the count.
    i.Count = 1;

    // Return the item.
    return i;
});

Ключ в снижении до IEnumerable<T>, в этот момент поставщик LINQ становится LINQ to Objects, что не доставит вам этой проблемы.

0 голосов
/ 24 января 2011

Ваш запрос не будет преобразован в правильный SQL, так как linq не будет знать, что делать с вашим дополнительным правом

Есть способы инициализации ваших пользовательских свойств.

Вы можете создать

частичная пустота OnCreated () {} * +1007 *

И напишите здесь свою пользовательскую инициализацию, и если вы Хотите загрузить после загрузки из базы данных, то вы можете Переопределить

защищенное переопределение void OnLoaded (bool initial) { base.OnLoaded (начальная); }

0 голосов
/ 24 января 2011

Проблема в том, что Linq to Entities пытается преобразовать все выражение в SQL. Это не совсем возможно с вашим «новым» утверждением.

Попробуйте следующее:

var ret = (from item in contex.Items
           select new Itemm
           ).ToList();
ret = (from item in ret
       select new Itemm
           {   
              Title = item.Title,
              Count = 1                                           
           }).ToList();

В основном вы проверяете, что результаты возвращаются с SQL-сервера (ToList () делает это), прежде чем пытаться восстановить их. Это не красиво, и вы, вероятно, можете немного его почистить, но приведенный выше код должен работать.

...