簡體   English   中英

EF Core邏輯查詢

[英]EF Core logical query

我有將EF Core與MVC結合使用的C#項目。

我有一個代表“虛擬”實體的控制器。 通過從兩個不同的表中進行選擇來創建此實體,然后按月和年對每個表進行匯總,然后將兩個結果連接起來。

我的問題是:是否可以(如果是,這是一個好的解決方案)用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)
                       });

這將引發錯誤,因為查詢結果未格式化為MyTable對象。 我嘗試為結果創建另一個viewModel,但是沒有成功(關於隱式轉換的相同錯誤)

viewModel:

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

有很多方法可以達到此要求。 如果表之間存在父子關系,則可以使用IncludeThenInclude

您也可以使用FromSql方法運行存儲過程,然后選擇所需的數據。

您也可以使用“ Select擴展方法來使用投影查詢。

您可以參考Microsoft為上述所有內容提供的官方文檔。

根據現在顯示的代碼進行編輯:

如圖所示,您的選擇返回一個匿名類型:

.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)

然后,在您的視圖中,您還必須更改模型以使用新的視圖模型。

獎金-

您應該考慮返回視圖模型,而不是直接將數據庫模型返回到視圖。 視圖模型有很多好處:

防止大規模分配漏洞(能夠發布超出您預期的用戶發布能力的漏洞)。 看到

可以為每個視圖量身定制它們,從而允許實現視圖邏輯之類的東西,這些邏輯不在數據庫模型中或僅特定於該視圖。

它們促進了松散耦合,以允許視圖根據數據庫模型的不同需求進行更改。

發問者添加編輯以顯示代碼之前的原始答案:

您可以在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中,他們將映射添加到稱為查詢類型和定義查詢的定義模型 (您的虛擬實體,視圖模型)中。

在2.1中,您可以創建一個視圖模型(稱為虛擬實體),將其添加到EF Context中,然后可以使用數據庫視圖,另一個EF查詢( 定義query )和/或匿名類型(有限制)對其進行查詢。 )。

例如:

給定一個視圖模型:

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)

如果由於某種原因這行不通或限制太多,我建議使用像dapper這樣的微型ORM,它可以接收原始SQL並將其映射到模型。

您更細微的問題對您有好處嗎?

簡短的答案-可能但總是檢查您的ORMS結果SQL並根據需要進行相應調整。

更長的答案-在不知道查詢或您現有的EF Core邏輯的復雜性以及它生成的結果SQL以及您的上下文的情況下,它必須具有怎樣的性能,多少用戶,多久被調用一次,等等...,我們無法回答這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM