[英]LINQ Query - How to parameterize a select distinct query
在嘗試使用“Distinct”查詢參數化“Select”時,我很難弄清楚我缺少什么。
這是我使用不同項目重復多次的代碼示例。
private void getCustomerCodeList(ObservableCollection<Model> FilteredData)
{
var distCustomerCode = FilteredData.Select(i => new { i.CustomerCode, i.FamilyName }).Distinct().OrderBy(x => x.FamilyName).ToList();
DistinctCustomerCodeList.Clear();
foreach (var item in distCustomerCode)
{
DistinctCustomerCodeList.Add(new Model() { CustomerCode = item.CustomerCode, FamilyName = item.FamilyName });
}
}
我正在嘗試將其轉換為一種方法,在該方法中我可以將“Select”和“Orderby”作為參數傳遞。 下面的代碼是我所能得到的,如果我傳入一個具有一個屬性的 lambda,它可以正常工作,但是一旦我嘗試添加一個屬性就會出錯。
public void getDistinct<TKey>(ObservableCollection<Model> FilteredData, Func<Model, TKey> myDistinctProperty, Func<TKey, TKey> mySortingProperty)
{
var distinct = FilteredData.Select(myDistinctProperty).Distinct().OrderBy(mySortingProperty).ToList();
DistinctCustomerCodeList.Clear();
foreach (var item in distinct )
{
DistinctCustomerCodeList.Add(new Model() { CustomerCode = item.ToString() });
}
}
如果我調用這個方法:
getDistinct<string>(FilteredData, x => x.CustomerCode, x => x);
它工作正常,但如果我嘗試:
getDistinct<string>(FilteredData, i => new { i.CustomerCode, i.FamilyName }, x => x.FamilyName)
它錯誤。
任何人都可以為我闡明這一點。
謝謝。
更新-
這是我收到的錯誤消息。
“IEnumerable”不包含“OrderBy”的定義,最佳擴展方法重載“ParallelEnumerable.OrderBy<Model, string>(ParallelQuery, Func<Model, string>)”需要“ParallelQuery”類型的接收器
我根據nalpnir提供的說明進行了更改,這是我更新后的代碼的樣子。
public void getDistinct<TKey>(ObservableCollection<Model> FilteredData, Func<Model, TKey> myDistinctProperty, Func<Model, string> mySortingProperty)
{
var distinct= FilteredData.Select(myDistinctProperty).Distinct().OrderBy(mySortingProperty).ToList();
DistinctCustomerCodeList.Clear();
foreach (var item in distinct)
{
DistinctCustomerCodeList.Add(new Model() { CustomerCode = item.ToString() });
}
}
這部分有上面提供的錯誤 (FilteredData.Select(myDistinctProperty).Distinct())
這是更新的方法調用:
getDistinct<Model>(FilteredData, i => new Model { FamilyName = i.FamilyName, CustomerCode = i.CustomerCode }, x => x.CustomerCode);
更新 2 -
感謝大家的反饋。 我最終使用了JeremyLakeman的答案,因為它最適合我正在從事的項目。
來自nalpnir的答案很棒,我將在未來嘗試實現它。
原因很簡單,你做的 LINQ 是錯誤的,有兩個原因,但同樣的原因本身:
您的 TKey 設置為字符串,因此當您說 new { i.CustomerCode, i.FamilyName } 時,它不知道如何從該表達式轉換為字符串。
排序的情況也是一樣,x是String類型,x不知道x.CustomerName是什么。
您應該使用模型作為 TKey,如下所示:
getDistinct<Model>(list, i => new Model { FamilyName = i.FamilyName, CustomerCode = i.CustomerCode }, x => x.CustomerCode);
更新:因為我注意到它沒有做你想做的事情,即能夠在不重復的情況下獲得它,我改變了一點想法,這樣你就可以繞過它,甚至使它更通用,這樣你就可以實現它你想要的任何課程,只要你做一些改變,我會解釋
public static List<T> getDistinct<T, TKey>(ObservableCollection<T> FilteredData, Func<T, TKey> myDistinctProperty, Func<T, string> mySortingProperty)
where T:Model, new()
{
var DistinctCustomerCodeList = new List<T>();
var distinct = FilteredData.GroupBy(myDistinctProperty).Select(x => x.First()).OrderBy(mySortingProperty).ToList();
foreach (var item in distinct)
{
DistinctCustomerCodeList.Add(new T() { CustomerCode = item.CustomerCode, FamilyName = item.FamilyName });
}
return DistinctCustomerCodeList;
}
正如您現在看到的,您有 2 個泛型,一個是 T,我限制為 Model 類型,另一個是在這種特殊情況下您想要的另一種類型,它將接受new { x.CustomerCode, x.FamilyName }
。 我會給你一個 .Net fiddle 的鏈接,所以你知道可以看到一個演示
演示:演示
你可以玩弄它。 基本上,只要您更改類型 T 的輸出並更改 foreach 中的 Add,您替換模型的任何類都將起作用。 Model 的繼承成員也可以使用,例如您實現以下內容:
public class ModelExtended:Model
{
public int NewProp { get; set; }
}
並且將 ObservableCollection 更改為 ObservableCollection 也將起作用,因為它們共享一些屬性
OrderBy()
需要一個泛型類型TKey
但參數mySortingProperty
顯式引用Model
。 更新方法定義中的參數,如下所示:
public void getDistinct<TKey>(ObservableCollection<Model> FilteredData, Func<Model, TKey> myDistinctProperty, Func<TKey, string> mySortingProperty)
您的第一個示例將 Model 的每個實例轉換為匿名類型,然后又重新轉換為 Model。 相反,通用的 distinct 方法應該創建一個只有請求字段的新模型。
public void getDistinct<TOrder>(ObservableCollection<Model> FilteredData, Func<Model, Model> distinct, Func<Model, TOrder> sort)
{
var distinct = FilteredData.Select(distinct).Distinct().OrderBy(sort).ToList();
DistinctCustomerCodeList.Clear();
DistinctCustomerCodeList.AddRange(distinct);
}
那么這應該可以工作,編譯器能夠推斷出泛型類型;
getDistinct(FilteredData, i => new Model{ i.CustomerCode, i.FamilyName }, x => x.FamilyName);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.