嘗試在分組后選擇多個多列:
兩個給定的串列:
List<Unit> unitList = new List<Unit>()
{
new Unit{ UnitId = 10, UnitName = "ETA"},
new Unit{ UnitId = 20, UnitName = "FSI"},
new Unit{ UnitId = 30, UnitName = "ECS"}
};
List<Employee> employeeList = new List<Employee>()
{
new Employee {EmployeeName = "John",UnitId=10,ProjectCode="ETAMYS",Salary=30000,JobLevel=3,JoiningDate=new DateTime(2014,3,5)},
new Employee {EmployeeName = "Jack",UnitId=10,ProjectCode="ETACHN",Salary=35000,JobLevel=3,JoiningDate=new DateTime(2011,3,5)},
new Employee {EmployeeName = "Albus",UnitId=10,ProjectCode="ETACHN",Salary=15000,JobLevel=4,JoiningDate=new DateTime(2011,3,5)},
new Employee {EmployeeName = "Ron",UnitId=20,ProjectCode="FSIAUS",Salary=10000,JobLevel=4,JoiningDate=new DateTime(2007,2,5)},
new Employee {EmployeeName = "Iwa",UnitId=20,ProjectCode="FSIAUS",Salary=15000,JobLevel=4,JoiningDate=new DateTime(2007,2,5)},
new Employee {EmployeeName = "Albert",UnitId=30,ProjectCode=null,Salary=20000,JobLevel=3,JoiningDate=new DateTime(2005,1,5)}
};
所需結果:顯示在每個單位中提取最低工資的員工的 EmployeeName、UnitId、Salary 和 ProjectCode。
我試過的:
var query15 = (from emp in employeeList
group emp by emp.UnitId
into g
select new
{
empUnits = g.Key,
empNames = g.Select(s=> s.EmployeeName),
empSalaries = g.Min(s => s.Salary),
projectCodes = g.Select(s=> s.ProjectCode)
}).ToList();
foreach (var unit in query15)
{
Console.WriteLine(unit.empNames " " unit.empUnits " " unit.empSalaries " " unit.projectCodes);
}
我正確地確定了最低工資以及相應的員工單位,但它沒有正確列印其余兩列 empNames 和 projectCodes,如下面的結果所示:

我基本上是 LINQ 的新手,并試圖處理各種任務,并陷入了要求在使用 group by 后列印各種列的任務中。我在這里先向您的幫助表示感謝!
uj5u.com熱心網友回復:
短格式:用于string.Join()將您的集合轉換為可以顯示的字串。
好的,現在是深度版本。啟用演講模式。
該.Select()方法的結果是一個SelectEnumerator<>包含以下資料的實體:
選擇器(
s => s.EmployeeName或s => s.ProjectCode)。對源列舉的參考(
g在這種情況下)。它本身是一個
Grouping<TKey, TElement>實體 (Grouping<int, Employee>),它包含:- 鍵值(
UnitId組的值)。 Employee對分組實體(物件)的參考集合。
- 鍵值(
所有這些都是為了讓您的代碼按需迭代名稱和專案代碼......在這種情況下,這不僅是很多開銷,而且也是不必要的 - 并且令人困惑 - 動態的。如果您更改任何員工記錄的EmployeeName或然后再次列舉 的物件,則該更改將被反映。但是,如果您更改其中任何一個,則不會反映更改,因為分組已經完成。ProjectCodequery15UnitId
通常,只要您期待它,這不是問題,但從代碼中并不能立即看出這種情況。
Select您可以通過將列舉轉換為具體的集合來簡化整個混亂,如下所示:
var query15 =
(
from emp in employeeList
group emp by emp.UnitId
into g
select new
{
empUnits = g.Key,
empNames = g.Select(s=> s.EmployeeName).ToArray(),
empSalaries = g.Min(s => s.Salary),
projectCodes = g.Select(s=> s.ProjectCode).ToArray()
}
).ToList();
使用您的樣本資料會導致projectCodes陣列翻倍,因此也許將該行更改為:
projectCodes = g.Select(s => s.ProjectCode).Distinct().ToArray()
現在你有一個具體物件的集合,沒有延遲執行,沒有捕獲的參考等等。這是一個物件圖,不會對您產生神秘的變化,并且將來使用empNamesandprojectCodes集合需要更少的時間,因為Select(Distinct如果您添加了)不必再次處理。
下一個問題是顯示幕。當您將字串添加到物件(字串連接)時,編譯器必須呼叫ToString()物件以獲取字串表示形式。對于絕大多數型別,這將導致型別名稱的某些版本,而不是表示物件內容的最佳猜測嘗試。
要獲得有用的字串,您需要自己做一些作業。幸運的是,該string.Join()方法是專門為這種場景創建的:
Console.WriteLine
(
string.Join(", ", unit.empNames) " "
unit.empUnits " "
unit.empSalaries " "
string.Join(", ", unit.projectCodes)
);
當然,只要您對結果感到滿意,您就可以保留原樣query15并在列舉中使用。string.Join()在這一點上,您不妨推遲對整體的列舉,query15而不是使用ToList().
(部分具體,因為它包含的物件本身是動態和復雜的。)
這個故事的主旨?C# 和 LINQ 是很棒的工具,但如果你不了解幕后發生的事情,它會讓你一頭霧水。
uj5u.com熱心網友回復:
現在我已經(過度)回答了問題的明顯部分,這是我錯過的一點:
所需結果:顯示在每個單位中提取最低工資的員工的 EmployeeName、UnitId、Salary 和 ProjectCode。
這讓事情變得完全不同,不是嗎。
然后我們需要按單位對員工進行分組,找到每個單位的最低工資值,然后選擇與該工資匹配的任何/所有員工。可能有多個,所以我們只列出工資與每個單位最低工資相匹配的所有員工。
以下是我的做法(在不嘗試向他人解釋代碼時,我通常不會寫評論):
var query15 =
(
// group our employee list by UnitId
from emp in employeeList
group emp by emp.UnitId into grp
// Find the lowest salary value
let minSalary = grp.Min(e => e.Salary)
// Now filter the grouped employees by that salary
from emp in grp
where emp.Salary == minSalary
select emp
);
從那里你可以在一個簡單的foreach回圈中列印出交易。我喜歡這個字串插值:
foreach (var emp in query15)
{
Console.WriteLine($"{emp.EmployeeName}\t{emp.UnitId}\t{emp.Salary}\t{emp.ProjectCode}");
}
或者,因為我喜歡漂亮的東西,讓我們為每個單位列印一個標題,其中包含單位詳細資訊(id、姓名、最低工資):
var query15a =
(
from emp in employeeList
join unit in unitList on emp.UnitId equals unit.UnitId
group emp by unit into grp
let minSalary = grp.Min(e => e.Salary())
select new
{
grp.Key.UnitId,
grp.Key.UnitName,
minSalary,
employees = grp.ToArray()
}
);
foreach (var unit in query15a)
{
Console.WriteLine($"Unit: {unit.UnitId} - {unit.UnitName}, Salary: ${unit.minSalary}");
foreach (var emp in unit.employees)
Console.WriteLine($"\t{emp.Name,-40} {emp.ProjectCode}";
Console.WriteLine();
}
更漂亮...如果您的員工姓名總是少于 40 個字符。根據需要調整:P
uj5u.com熱心網友回復:
我不確定這是否會導致任何性能問題。但是,對于您的問題,可以由此實作。您可以將必要的屬性添加到選定的物件。
var foo = employeeList.GroupBy(g => g.UnitId).Select(s =>
employeeList.Where(ss => ss.UnitId == s.Key).Select(s => new Employee {
Salary = s.Salary,
UnitId = s.UnitId
}).OrderBy(s => s.Salary).FirstOrDefault());
foreach (var fo in foo)
{
Console.WriteLine(fo.Salary "|" fo.UnitId);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/516536.html
標籤:C#。网林克
