c# – Dynamic Linq – 对具有“动态”类型成员的对象执行查询
我试图使用动态
linq查询来检索IEnumerable< T>从对象集合(
Linq到Object),集合中的每个对象都有一个内部集合,其中包含存储数据的另一组对象,这些值通过外部集合中的索引器访问
当您使用强类型对象但我的对象将数据存储在动态类型的成员中时,动态linq查询会按预期返回已过滤的集,请参阅下面的示例: public class Data { public Data(string name,dynamic value) { this.Name = name; this.Value = value; } public string Name { get; set; } public dynamic Value { get; set; } } public class DataItem : IEnumerable { private List<Data> _collection; public DataItem() { _collection = new List<Data>(); } public dynamic this[string name] { get { Data d; if ((d = _collection.FirstOrDefault(i => i.Name == name)) == null) return (null); return (d.Value); } } public void Add(Data data) { _collection.Add(data); } public IEnumerator GetEnumerator() { return _collection.GetEnumerator(); } } public class Program { public void Example() { List<DataItem> repository = new List<DataItem>(){ new DataItem() { new Data("Name","Mike"),new Data("Age",25),new Data("BirthDate",new DateTime(1987,1,5)) },new DataItem() { new Data("Name","Steve"),30),new DateTime(1982,10)) } }; IEnumerable<DataItem> result = repository.AsQueryable<DataItem>().Where("it["Age"] == 30"); if (result.Count() == 1) Console.WriteLine(result.Single()["Name"]); } 当我运行上面的例子时,我得到:运算符’==’与操作数类型’Object’和’Int32’不兼容 动态成员是否与Dynamic Linq查询不兼容?还是有另一种构造表达式的方法,这些表达式在处理动态类型的成员时会正确评估 非常感谢你的帮助. 解决方法
两者都可以一起工作.在进行比较之前,只需转换为Int32,如下所示: IEnumerable<DataItem> result = repository.AsQueryable<DataItem>().Where("Int32(it["Age"]) == 30"); 编辑1:尽管如此,与Linq相关的动态绑定的使用通常受到限制,因为表达式树中不允许动态操作.考虑以下Linq-To-Objects查询: IEnumerable<DataItem> result = repository.AsQueryable(). Where(d => d["Age"] == 30); 由于上述原因,此代码段无法编译. 编辑2:在您的情况下(与Dynamic Linq一起),有一些方法可以解决编辑1和原始问题中提到的问题.例如: // Variant 1: Using strings all the way public void DynamicQueryExample(string property,dynamic val) { List<DataItem> repository = new List<DataItem>(){ new DataItem() { new Data("Name",5)) },new DataItem() { new Data("Name",10)) } }; // Use string comparison all the time string predicate = "it["{0}"].ToString() == "{1}""; predicate = String.Format(whereClause,property,val.ToString()); var result = repository.AsQueryable<DataItem>().Where(predicate); if (result.Count() == 1) Console.WriteLine(result.Single()["Name"]); } Program p = new Program(); p.DynamicQueryExample("Age",30); // Prints "Steve" p.DynamicQueryExample("BirthDate",10)); // Prints "Steve" p.DynamicQueryExample("Name","Mike"); // Prints "Steve" (nah,just joking...) 要么: // Variant 2: Detecting the type at runtime. public void DynamicQueryExample(string property,string val) { List<DataItem> repository = new List<DataItem>(){ new DataItem() { new Data("Name",10)) } }; string whereClause = "{0}(it["{1}"]) == {2}"; // Discover the type at runtime (and convert accordingly) Type type = repository.First()[property].GetType(); string stype = type.ToString(); stype = stype.Substring(stype.LastIndexOf('.') + 1); if (type.Equals(typeof(string))) { // Need to surround formatting directive with "" whereClause = whereClause.Replace("{2}",""{2}""); } string predicate = String.Format(whereClause,stype,val); var result = repository.AsQueryable<DataItem>().Where(predicate); if (result.Count() == 1) Console.WriteLine(result.Single()["Name"]); } var p = new Program(); p.DynamicQueryExample("Age","30"); p.DynamicQueryExample("BirthDate","DateTime(1982,10)"); p.DynamicQueryExample("Name","Mike"); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |