我有一个这样的对象列表(我正在使用.NET 3.5)
var dt = getResultTable(...);
var value1 = dt.Rows[0].GetValue<int>("ColumnName");
var value2 = dt.Rows[0].GetValue<int>("ColumnName", 10); // you can also specify a different default value if needed
现在,我尝试使用Linq在列表中进行搜索。 这按预期工作
public class MyObjects
{
public object Name { get; set; }
public bool Case { get; set; }
}
List<MyObjects> test = new List<MyObjects> {
new MyObjects { Name = "one" },
new MyObjects { Name = "two" },
new MyObjects { Name = "three" },
new MyObjects { Name = "four" },
new MyObjects { Name = "one1" },
new MyObjects { Name = "two1" },
new MyObjects { Name = "three1" },
new MyObjects { Name = "four1" },
new MyObjects { Name = "one2" },
new MyObjects { Name = "two2" },
new MyObjects { Name = "three2" },
new MyObjects { Name = "four2" },
};
使用动态Linq,这也可以按预期工作
var tmp = test
.Select(p => p.Name)
.Where(x => x.ToString().Contains("One", StringComparison.InvariantCultureIgnoreCase))
;
但是,当尝试使用区分大小写(不区分大小写)时,动态操作会失败。
var dtmp = test.AsQueryable()
.Select(p => p.Name)
.Where("ToString().Contains(@0)", "one")
;
错误是
var dtmp2 = test.AsQueryable()
.Select(p => p.Name)
.Where("ToString().Contains(@0, @1)", "one", StringComparison.InvariantCultureIgnoreCase)
;
我的第一个尝试是编写一个这样的Contains()扩展名
No applicable method 'Contains' exists in type 'String'
似乎Dynamic Linq不知道我的扩展名。我发现了(据此) https://social.msdn.microsoft.com/Forums/en-US/39763339-1700-486f-9800-badd257e921e/custom-extension-methods-and-dynamic-linq-dynamic-expression-api?forum=linqprojectgeneral
Dynamic Linq无法非常轻松地使用(静态)扩展的。
所以:
以常规方法转换扩展名。但是,如何为每个ToString()做到这一点,是否有可能还是应该在MyObject中编写一个方法,然后对特定对象使用linq?
修改动态库代码以接受硬编码的(my)静态扩展。
其他建议?
注意:我可以使用简单的if / else区分大小写,并具有两种动态效果,但由于我的应用程序使用了一些复杂的过滤功能,因此我更喜欢解决动态方式。
先谢谢您
答案 0 :(得分:1)
如果您的应用程序需要动态过滤器功能,则建议调用者传递一个谓词。
这可以将关注点分离并简化单元测试。
此外,当调用者传递谓词时,不需要IF / ELSE语句。
var predicate = new Predicate<string>(str => str.Contains("one"));
var tmp = test.Select(p => p.Name).Where(predicate);
答案 1 :(得分:0)
您尝试使用System.Linq.Dynamic.Core是因为该库似乎可以处理您的示例C#代码。