如何使用动态Linq与List <dynamic>对象

时间:2017-06-05 18:03:13

标签: c# .net linq dynamic-linq

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

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的行为与上面的代码相似。我在这里做错了什么,或者我应该采取不同的方法?如果需要,我可以提供更多细节。

提前致谢!

1 个答案:

答案 0 :(得分:0)

最后我得到了一个有效的解决方案!它可能不是最有效的,但它适合我的需要,并允许我保持我希望保留的动态性质。解决方案是完全放弃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;
        }