[英]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; }
}
有很多方法可以達到此要求。 如果表之間存在父子關系,則可以使用Include
和ThenInclude
。
您也可以使用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.