【问题标题】:How do I search a dynamic object IEnumerable<dynamic> using a dynamically built lambda expression?如何使用动态构建的 lambda 表达式搜索动态对象 IEnumerable<dynamic>?
【发布时间】:2017-04-08 16:46:59
【问题描述】:

之前对我上一个问题有很大帮助,谢谢vyrp , How do I create and populate a dynamic object using a dynamically built lambda expression

我现在正在寻找动态对象,并且和以前一样,我不知道对象属性,因此直到运行时我才知道要搜索的内容。

这是构建动态对象的代码:

        // 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));

但显然该代码不起作用。我尝试了很多不同的尝试,都没有成功,所以我正在寻找建议。谢谢

【问题讨论】:

  • 不起作用是什么意思?请详细说明。
  • 那么编译错误是什么?

标签: c# linq lambda where dynamicobject


【解决方案1】:

由于您知道查询的dynamic 元素实际上是ExpandoObject,因此IDictionary&lt;string, object&gt;&gt;,您可以安全地将其转换为字典接口并使用它按名称访问属性值,而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);
    }));

【讨论】:

  • 试试.Cast&lt;IDictionary&lt;string, object&gt;&gt;() ^^
  • @AgentFire 它会改变查询的结果,也不允许使用预定义的属性访问器,比如r.PrimaryData
猜你喜欢
  • 1970-01-01
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多