如何使用动态构建的 lambda 表达式搜索动态对象 IEnumerable<dynamic>?
How do I search a dynamic object IEnumerable<dynamic> using a dynamically built lambda expression?
之前对我之前的问题有很大的帮助,谢谢vyrp
,
我现在正在搜索动态对象,和以前一样,我不知道对象的属性,因此直到运行时才知道我要搜索的内容。
下面是构建动态对象的代码:
// Get list of optional fields
var optFieldList = await _tbList_FieldRepository.GetAsync(lf => lf.ListID == listId && lf.DisplayInList == true);
// order list of optional fields
optFieldList.OrderBy(lf => lf.DisplayOrder);
// Get base Data excluding Inactive if applicable
IEnumerable<tbList_Data> primaryData = await _tbList_DataRepository.GetAsync(ld => ld.ListID == listId && (ld.IsActive == includeInactive ? ld.IsActive : true));
// Build IEnumerable<dynamic> from base results plus any optional fields to be displayed in table
var results = primaryData.Select(pd => {
dynamic result = new System.Dynamic.ExpandoObject();
result.Id = pd.ID;
result.PrimaryData = pd.PrimaryData;
result.DisplayOrder = pd.DisplayOrder;
result.IsActive = pd.IsActive;
foreach (var optField in optFieldList)
{
switch (optField.FieldType.ToLower()) {
case "text":
((IDictionary<string, object>)result).Add(optField.FieldName, pd.tbList_DataText.Where(ld => ld.DataRowID == pd.ID && ld.ListColumnID == optField.ID).Select(ld => ld.DataField).DefaultIfEmpty("").First());
break;
}
}
return result;
});
出于测试目的,我有 2 个动态字段,"PhoneNumber" 和 "FuelType"
我可以搜索已知字段,即 PrimaryData,没问题,如下所示。
results = results.Where(r => r.PrimaryData.Contains(searchString));
如果我在设计时知道字段 PhoneNumber,则以下内容将起作用
results = results.Where(r => r.PhoneNumber.Contains(searchString));
但我想做的是:
results = results.Where(r => r.PrimaryData.Contains(searchString)
|| foreach(var optField in optFieldList)
{
r.optField.FieldName.Contains(searchString)
})
结束于
results = results.Where(r =>
r.PrimaryData.Contains(searchString)
|| r.PhoneNumber.Contains(searchString) ||
r.FuelType.Contains(searchString));
但显然该代码不起作用。我尝试了很多不同的尝试,none 成功了,所以我正在寻找建议。谢谢
由于您知道查询的 dynamic
元素实际上是 ExpandoObject
,因此 IDictionary<string, object>>
,您可以安全地将其转换为字典接口并使用它来访问 属性 值的名称,而 Enumerable.Any 方法可用于模拟动态 ||
条件:
results = results.Where(r => r.PrimaryData.Contains(searchString)
|| optFieldList.Any(f =>
{
object value;
return ((IDictionary<string, object>)r).TryGetValue(f.FieldName, out value)
&& value is string && ((string)value).Contains(searchString);
}));
之前对我之前的问题有很大的帮助,谢谢vyrp
,
我现在正在搜索动态对象,和以前一样,我不知道对象的属性,因此直到运行时才知道我要搜索的内容。
下面是构建动态对象的代码:
// Get list of optional fields
var optFieldList = await _tbList_FieldRepository.GetAsync(lf => lf.ListID == listId && lf.DisplayInList == true);
// order list of optional fields
optFieldList.OrderBy(lf => lf.DisplayOrder);
// Get base Data excluding Inactive if applicable
IEnumerable<tbList_Data> primaryData = await _tbList_DataRepository.GetAsync(ld => ld.ListID == listId && (ld.IsActive == includeInactive ? ld.IsActive : true));
// Build IEnumerable<dynamic> from base results plus any optional fields to be displayed in table
var results = primaryData.Select(pd => {
dynamic result = new System.Dynamic.ExpandoObject();
result.Id = pd.ID;
result.PrimaryData = pd.PrimaryData;
result.DisplayOrder = pd.DisplayOrder;
result.IsActive = pd.IsActive;
foreach (var optField in optFieldList)
{
switch (optField.FieldType.ToLower()) {
case "text":
((IDictionary<string, object>)result).Add(optField.FieldName, pd.tbList_DataText.Where(ld => ld.DataRowID == pd.ID && ld.ListColumnID == optField.ID).Select(ld => ld.DataField).DefaultIfEmpty("").First());
break;
}
}
return result;
});
出于测试目的,我有 2 个动态字段,"PhoneNumber" 和 "FuelType"
我可以搜索已知字段,即 PrimaryData,没问题,如下所示。
results = results.Where(r => r.PrimaryData.Contains(searchString));
如果我在设计时知道字段 PhoneNumber,则以下内容将起作用
results = results.Where(r => r.PhoneNumber.Contains(searchString));
但我想做的是:
results = results.Where(r => r.PrimaryData.Contains(searchString)
|| foreach(var optField in optFieldList)
{
r.optField.FieldName.Contains(searchString)
})
结束于
results = results.Where(r =>
r.PrimaryData.Contains(searchString)
|| r.PhoneNumber.Contains(searchString) ||
r.FuelType.Contains(searchString));
但显然该代码不起作用。我尝试了很多不同的尝试,none 成功了,所以我正在寻找建议。谢谢
由于您知道查询的 dynamic
元素实际上是 ExpandoObject
,因此 IDictionary<string, object>>
,您可以安全地将其转换为字典接口并使用它来访问 属性 值的名称,而 Enumerable.Any 方法可用于模拟动态 ||
条件:
results = results.Where(r => r.PrimaryData.Contains(searchString)
|| optFieldList.Any(f =>
{
object value;
return ((IDictionary<string, object>)r).TryGetValue(f.FieldName, out value)
&& value is string && ((string)value).Contains(searchString);
}));