EF6 могу ли я обновить модель / таблицу после выполнения лямбда-запроса?

#entity-framework #rest #asp.net-web-api #lambda

#entity-framework #отдых #asp.net-web-api #лямбда

Вопрос:

Я выполняю лямбда-запросы к моделям (я делаю проекцию с другими классами — GameBankVM, GameCouponBankVM), и в конце я хотел бы выполнить цикл по результату запроса и обновить поле модели. Но я получаю объект или сложный тип ‘EPINMiddleWareAPI.Модели.GameBankVM’ не может быть создан в запросе LINQ to Entities.

Вот мой пример кода:

  var gameBankResult = await (context.GameBanks.Where(g => g.productCode == initiate.productCode)
                .Take(initiate.quantity)
                .Select(g => new GameBankVM
                {
                    quantity = g.quantity,
                    currency = g.currency,
                    initiationResultCode = g.initiationResultCode,
                    productCode = g.productCode,
                    productDescription = g.productDescription,
                    referenceId = g.referenceId,
                    responseDateTime = g.responseDateTime,
                    unitPrice = g.unitPrice,
                    totalPrice = g.totalPrice,
                    coupons = g.coupons.Select(c => new GameCouponBankVM
                    {
                        Pin = c.Pin,
                        Serial = c.Serial,
                        expiryDate = c.expiryDate
                    }).ToList() 
                })).ToListAsync(); 

            if (gameBankResult.Count() != 0)
            {
                foreach (var item in gameBankResult)
                {
                    item.referenceId = initiate.referenceId;
                    context.Entry(item).State = System.Data.Entity.EntityState.Modified;
                }


                await context.SaveChangesAsync();
                return Ok(gameBankResult);
            }
 

Как я могу обновить referenceId в моей модели / таблице GameBank?

Ответ №1:

В этом сценарии ваши данные не будут обновлены, потому что ваш запрос возвращает список GameBankVM, а не список GameBank, теперь, технически говоря, вы нарушаете SRP, вам следует либо обновить свои данные, либо запросить свои данные не одним и тем же методом, вы можете реорганизовать свой метод, напримерэто :

1. — Создайте частный метод для обновления данных, в этом случае вы запрашиваете напрямую GameBank, перебираете записи списка, вносите изменения и сохраняете их в базе данных, этот же метод может возвращать список GameBank, чтобы избежать повторного обхода базы данных.

2.- В контроллере после вызова вашего нового метода вы можете запустить запрос преобразования, чтобы преобразовать список GameBank в Список GameBankVM и вернуть его в представление.

Есть много других способов сделать это, я просто рекомендую это как менее эффективный способ заставить ваш контроллер работать. Но если вы хотите улучшить ситуацию, вы можете создать бизнес-уровень, на котором вы разрешаете все свои бизнес-правила, или вы можете использовать шаблоны, такие как CQS или CQRS.

Комментарии:

1. Спасибо за ваш ответ. На самом деле я использовал GameBankVM и GameCouponBankVM для проектирования запросов. Все, что я хочу сделать, это запросить базу данных и, если есть результаты, обновить их.

2. Точно, я понимаю, что вам это нужно для прогнозирования запросов, дело в том, что у вас не будет отслеживания в прогнозах запросов без объекта в проекции, посмотрите на это: docs.microsoft.com/en-us/ef/core/querying/tracking

3. Ваш запрос возвращает объекты виртуальной машины, которые не отслеживаются EF.

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