【问题标题】:How to use dynamic Linq with List<dynamic> object如何将动态 Linq 与 List<dynamic> 对象一起使用
【发布时间】:2017-06-05 18:03:13
【问题描述】:

我有一个动态对象列表,我正在尝试在其上使用动态 Linq。我正在使用动态对象,因为我不知道将进入对象的属性。 Linq 在我的动态对象上工作,但是,为了避免巨大的硬编码 if 语句,我想使用动态 Linq 来搜索我的列表。代码 sn-p 的上半部分有效,但我需要它动态工作,以便我可以从我的属性创建查询字符串并以这种方式过滤。

public List<dynamic> GetFilteredLocationData(List<dynamic> locationData, string searchTerm){

                //Does work
                List<dynamic> totalResults = locationData.Where(x => x.Street.ToLower().Contains(searchTerm.ToLower()) ||
                    x.Street.ToLower().Contains(searchTerm.ToLower()) ||
                    x.Zip.ToLower().Contains(searchTerm.ToLower()));

                //Does not work
                var testQueryString = "(Street == \"king\")";
                var testResult = locationData.Where(testQueryString);


                return totalResults;
            }       

我收到的运行时错误:“对象”类型中不存在“街道”属性或字段

该错误是有意义的,因为默认情况下对象不包含“Street”,但我希望动态 Linq 的行为类似于它上面的代码。我在这里做错了什么,还是应该采取不同的方法?如果需要,我可以提供更多详细信息。

提前致谢!

【问题讨论】:

  • 在使用之前检查null的属性。
  • 您确实需要重新考虑您的设计。一般来说,C# 和 CLR 不适合使用动态变量。动态的意图是特殊目的。我认为你已经在这种情况下过度使用它了。
  • 不管它的名字如何,我认为 Dynamic LINQ 不能与 dynamic 数据一起使用。 IQueryable 静态依赖于ElementType 属性,dynamic 的静态类型为object
  • 我正在编写一个小部件,因此这段代码现在在两个地方使用,以后还会在更多地方使用。我正在尝试使其可扩展,因此我不必稍后添加 if 或 switch 块来使用不同的视图模型。考虑到这一点,如果不是动态或扩展对象,任何想法最干净的解决方案是什么?接口?感谢大家的帮助。
  • 通用接口? IFilterable&lt;T&gt;?

标签: c# .net linq dynamic-linq


【解决方案1】:

我终于找到了一个可行的解决方案!它可能不是最有效的,但它可以满足我的需求,让我能够保持我希望保留的动态特性。解决方案是完全放弃 Linq 并使用旧的 for-each 循环。重要的部分是 IDictionary,它允许我在每一行中搜索键值对。这与我想要的功能相同,只是放弃了 linq。

public List<dynamic> GetFilteredLocationData(List<dynamic> locationData, string searchTerm){
                List<dynamic> totalResults = new List<dynamic>();
                List<string> locationProperties = new List<string> {"dynamic properties here, this was filled by call to DB for info pertaining to certain location combined with unique data"}
                foreach (var locData in locationData)
                {
                    var currentLoc = locData;
                    var currentLocDict = (IDictionary<string, object>)currentLoc;

                    bool containsSearchTerm = CheckIfLocationContainsSearch(currentLocDict, allLocationProperties, searchTerm);
                    if (containsSearchTerm)
                    {
                        totalResults.Add(locData);
                    }
                }
            }

            public bool CheckIfLocationContainsSearch(IDictionary<string,object> location, List<string> locationProperties, string searchTerm){

            foreach (var locProp in locationProperties)
            {
                if (location[locProp].ToString().ToLower().Contains(searchTerm))
                {
                    return true;
                }
            }
            return false;
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    相关资源
    最近更新 更多