首页 > 解决方案 > LINQ 查询 - 如何参数化选择不同的查询

问题描述

在尝试使用“不同”查询参数化“选择”时,我很难弄清楚我缺少什么。

这是我多次重复选择不同项目的代码示例。

    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的答案很棒,我会在未来尝试实现它。

标签: c#linq

解决方案


原因很简单,您正在做的 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 也将起作用,因为它们共享一些属性


推荐阅读