Dar*_*ura 7 c# lambda expression-trees dynamic-linq
我试图使用动态linq查询从对象集合(Linq到Object)中检索IEnumerable <T>,集合中的每个对象都有一个内部集合,其中包含存储数据的另一组对象,这些值通过外部集合中的索引器访问
当您使用强类型对象但我的对象将数据存储在动态类型的成员中时,动态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"),
new Data("Age", 30),
new Data("BirthDate", new DateTime(1982, 1, 10))
}
};
IEnumerable<DataItem> result = repository.AsQueryable<DataItem>().Where("it[\"Age\"] == 30");
if (result.Count() == 1)
Console.WriteLine(result.Single()["Name"]);
}
Run Code Online (Sandbox Code Playgroud)
当我运行上面的例子时,我得到:运算符'=='与操作数类型'Object'和'Int32'不兼容
动态成员是否 与Dynamic Linq查询不兼容?还是有另一种构造表达式的方法,这些表达式在处理动态类型的成员时会正确评估
非常感谢你的帮助.
动态成员是否与动态 Linq 查询不兼容?或者是否有另一种构造表达式的方法,在处理动态类型的成员时可以正确计算?
两者可以一起工作。只需在进行比较之前先转换为 Int32,如下所示:
IEnumerable<DataItem> result =
repository.AsQueryable<DataItem>().Where("Int32(it[\"Age\"]) == 30");
Run Code Online (Sandbox Code Playgroud)
编辑 1:话虽如此,与 Linq 相关的动态绑定的使用通常受到限制,因为表达式树中不允许动态操作。考虑以下 Linq-To-Objects 查询:
IEnumerable<DataItem> result = repository.AsQueryable().
Where(d => d["Age"] == 30);
Run Code Online (Sandbox Code Playgroud)
由于上述原因,此代码片段将无法编译。
编辑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", "Mike"),
new Data("Age", 25),
new Data("BirthDate", new DateTime(1987, 1, 5))
},
new DataItem() {
new Data("Name", "Steve"),
new Data("Age", 30),
new Data("BirthDate", new DateTime(1982, 1, 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", new DateTime(1982, 1, 10)); // Prints "Steve"
p.DynamicQueryExample("Name", "Mike"); // Prints "Steve" (nah, just joking...)
Run Code Online (Sandbox Code Playgroud)
或者:
// 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", "Mike"),
new Data("Age", 25),
new Data("BirthDate", new DateTime(1987, 1, 5))
},
new DataItem() {
new Data("Name", "Steve"),
new Data("Age", 30),
new Data("BirthDate", new DateTime(1982, 1, 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, property, 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, 1, 10)");
p.DynamicQueryExample("Name", "Mike");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6154 次 |
| 最近记录: |