簡體   English   中英

LINQ 查詢 - 如何參數化選擇不同的查詢

[英]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.

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