c# - 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的答案很棒,我会在未来尝试实现它。
解决方案
原因很简单,您正在做的 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 也将起作用,因为它们共享一些属性
推荐阅读
- r - 如何应用机器学习技术/如何使用模型输出
- python - Python 从一个运行多个脚本
- sql - SQL - 具有多个日期的条件窗口
- ios - 将 Gif 从 URL 加载到 CollectionViewCell
- python - 如何从 seaborn 的 KDE distplot 对象中提取 bin?
- sql - .Select with EF Core 在视图中返回 ModelError
- node.js - NodeJs:Sequelize(版本 - 5+)N:M 关联不起作用
- php - 如何为 arangodb-php 中的流式事务增加“maxTransactionSize”
- python - Python:在对数刻度的两条曲线之间拟合圆,以连接圆的原点
- vue.js - VueJS PWA's - 通过 GenerateSW 启用 Workbox “调试”