Изменить свойство Linq на Sql Entity в запросе - PullRequest
3 голосов
/ 12 декабря 2010

У меня есть 2 таблицы Products и ProductDetails.Продукты содержат всю информацию о моих запасах, а ProductDetails используется, чтобы позволить изменениям цены продукта в системе заблаговременно до того, как они вступят в действие.

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

var products = from p in Products
               from pd in ProductDetails
                .Where(pd => pd.ProductID == p.ID && pd.CommenceDate <= DateTime.Now)
                .DefaultIfEmpty()
               where p.InUse == true
               select p;

Сначала я подумал, что смогу достичь того, что хотел, объявив новый продукт в избранном, например:

var products = from p in Products
               from pd in ProductDetails
                .Where(pd => pd.ProductID == p.ID && pd.CommenceDate <= DateTime.Now)
                .DefaultIfEmpty()
               where p.InUse == true
               select new Product {
                    ID = p.ID,
                    Description = p.Description,
                    ....
                    Cost = pd.Cost.HasValue ? pd.Cost : p.Cost,
                    Price = pd.Price.HasValue ? pd.Price : p.Price,
                    ...
               };

.следующая ошибка:

Explicit construction of entity type 'LINQPad.User.Product' in query is not allowed

Есть ли простой способ сказать «вернуть товар и при необходимости заменить некоторые значения свойств»?

1 Ответ

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

У вас есть 3 варианта:

  • обработка элементов после их выборка - т.е.

    var products = ( /* first query */ ).ToList();
    foreach(var item in products) {
        item.Cost = ...;
        item.Price = ...;
    }
    // and probably submit changes
    
  • создатьнесвязанный тип (вне модели) для проецирования;даже тип anon:

    var products = /* most of second query */
                   select new { // <==== not a Product
                        ID = p.ID,
                        Description = p.Description,
                        ....
                        Cost = pd.Cost.HasValue ? pd.Cost : p.Cost,
                        Price = pd.Price.HasValue ? pd.Price : p.Price,
                        ...
                   };
    
  • почти так же, как и выше, но с нарушением композиции (через AsEnumerable(), что означает, что мы возвращаемся к LINQ-to-Objects для любогоследует) и создание измененной версии вне контекста данных

    var products = from prod in (/* first query */).AsEnumerable()
                   select new Product {
                        ID = p.ID,
                        Description = p.Description,
                        ....
                        Cost = pd.Cost.HasValue ? pd.Cost : p.Cost,
                        Price = pd.Price.HasValue ? pd.Price : p.Price,
                        ...
                   };
    

Редактировать комментарии;другой вариант - блок итератора;блоками итератора являются потоковые устройства;компилятор творит много магии, чтобы гарантировать, что ваш код обрабатывает только один элемент («возвращение дохода») за раз - он не читает все данные, прежде чем что-либо возвращать:

static IEnumerable<Product> SomeMethod(IEnumerable<Product> products) {
    foreach(p in products) {
        p.Foo = ...
        p.Bar = ...
        yield return p;
    }
}

Теперь передайте последовательностьпродукты с помощью этого метода.

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