EF Core логический запрос - PullRequest
       5

EF Core логический запрос

0 голосов
/ 03 октября 2018

У меня есть проект C #, который использует EF Core с MVC.

У меня есть контроллер, представляющий «виртуальную» сущность.Эта сущность создается путем выбора из двух разных таблиц, агрегирования каждой из них по месяцам и годам, а затем связывания двух результатов.

Мой вопрос: возможно ли это (и если да, то хорошо ли эторешение) чтобы сделать эту сумму с EF Core?Или мне просто пройтись по элементам с помощью C # и агрегировать их так, как я хочу?

РЕДАКТИРОВАТЬ : В настоящее время я согласен с этим:

 public IEnumerable<MyTable> Get...(int month, int year)
        return _context.MyTable
           //.Include(b => b.)
           .Where(t => t.Month == month && t.Year == year)
           .GroupBy(a => a.BrokerId)
           .Select(param1 => new {
                                   BrokerId = param1.Key,
                                   TotalCommissionAmountBruto = param1.Sum(s => s.CommissionAmountBruto),
                                   TotalCommissionAmountNeto = param1.Sum(s=>s.CommissionAmountNeto)
                       });

Thisвыдает ошибку, потому что результат запроса не отформатирован как MyTable объект.Я попытался создать другую модель представления для результата, но безуспешно (та же ошибка с неявным приведением)

ViewModel:

public class MyViewModel : DtoBase
{
    public int brokerId { get; set; }
    public int TotalCommissionAmountBruto { get; set; }
    public int TotalCommissionAmountNeto { get; set; }
}

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Редактирование на основе кода, который теперь отображается в вопросе:

Ваш выбор, как показано, возвращает анонимный тип:

.Select(param1 => new {
                         BrokerId = param1.Key,
                         TotalCommissionAmountBruto = param1.Sum(s => s.CommissionAmountBruto),
                         TotalCommissionAmountNeto = param1.Sum(s=>s.CommissionAmountNeto)
                       });

Верните модель представления, и вам следуетбыть установленным:

.Select(param1 => new MyViewModel {
                                    BrokerId = param1.Key,
                                    TotalCommissionAmountBruto = param1.Sum(s => s.CommissionAmountBruto),
                                    TotalCommissionAmountNeto = param1.Sum(s=>s.CommissionAmountNeto)
                       });

Затем измените свой тип возврата в действии с:

public IEnumerable<MyTable> Get...(int month, int year)

на

public IEnumerable<MyViewModel> Get...(int month, int year)

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

Bonus -

Вам следует рассмотреть возможность возврата модели представления вместо прямого возврата модели базы данных в представление.Модели просмотра имеют много преимуществ:

Защищает от уязвимости массового назначения (возможность публиковать больше, чем вы хотели, чтобы пользователь публиковал).См.

Они могут быть адаптированы для каждого видадопускает такие вещи, как логика для реализуемого представления, которое отсутствует в модели базы данных или относится только к этому представлению.

Они обеспечивают слабую связь, позволяя представлению изменяться в зависимости от потребностей, чем модель базы данных..

Исходный ответ перед добавлением спрашивающего редактировать, чтобы показать код:

Вы можете использовать функции группировки и агрегирования в EF Core.Взгляните на образец LINQ GroupBy в этих документах для базового примера.Это может быть намного сложнее, чем показано в примере.

var query = context.Orders
    .GroupBy(o => new { o.CustomerId, o.EmployeeId })
    .Select(g => new
        {
          g.Key.CustomerId,
          g.Key.EmployeeId,
          Sum = g.Sum(o => o.Amount),
          Min = g.Min(o => o.Amount),
          Max = g.Max(o => o.Amount),
          Avg = g.Average(o => Amount)
        });

Выше приведена основная идея группировки, а затем использования некоторых агрегатных функций.

Если у вас написан SQLдля этого и предпочитаете использовать его, вы также можете иметь EF Core, вызывающий необработанный SQL , который на первый взгляд может показаться слишком ограничительным в том смысле, что вы должны иметь карту результатов для сущности (а в вашем случае это не так),В 2.1 они добавили отображение к вашей собственной определенной модели (ваша виртуальная сущность, View Model), называемой типами запросов и определяющей запрос.

В 2.1 вы могли создать представлениемодель (то, что вы называете виртуальной сущностью), добавьте ее в свой контекст EF, а затем вы можете запросить ее с помощью представления базы данных, другого запроса EF ( определяющий запрос ) и / или анонимных типов (с ограничениями).

Например:

С учетом модели представления:

public class MySpecialModel
{  
  public string Name { get; private set; }
  public int Count { get; private set; }
}

Вы добавили бы ее в свой контекст:

public DbQuery<MySpecialModel> MySpecialModel {get;set;}

Тогда вы быНазовите это:

var results = context.MySpecialModel.FromSql("select name,count from a join b on b.id=a.id)

Если по какой-то причине это не работает или слишком ограничивает, я рекомендую использовать микро ORM, например dapper , который может взять ваш сырой SQL и отобразить его намодель.

Ваш более нюансированный вопрос - это хорошо?

Короткий ответ - возможно, но всегда проверяйте результирующий SQL-код ORMS и корректируйте его в соответствии с вашими потребностями.

Более длинный ответ - без знания сложности запроса или существующей логики EF Core и результирующего SQLон генерирует И ваш контекст, насколько быстрым он должен быть, сколько пользователей, как часто он будет вызываться и т. д., мы не можем ответить на этот вопрос.

0 голосов
/ 03 октября 2018

Есть много способов выполнить это требование.Если между таблицами есть родительско-дочерние отношения, вы можете использовать Include и ThenInclude.

Вы можете запустить хранимую процедуру также с помощью метода FromSql и выбрать необходимые данные.

Вы также можете использовать проекционный запрос, используя Select метод расширения.

Вы можете обратиться к официальной документации, предоставленной Microsoft для всего вышеперечисленного.

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