Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 动态Linq-对成员类型为“的对象执行查询”;“动态”;_C#_Lambda_Expression Trees_Dynamic Linq - Fatal编程技术网

C# 动态Linq-对成员类型为“的对象执行查询”;“动态”;

C# 动态Linq-对成员类型为“的对象执行查询”;“动态”;,c#,lambda,expression-trees,dynamic-linq,C#,Lambda,Expression Trees,Dynamic Linq,我尝试使用动态linq查询从对象集合(linq to object)检索IEnumerable,集合中的每个对象都有一个内部集合,其中包含另一组存储数据的对象,这些值通过外部集合的索引器访问 使用强类型对象时,动态linq查询将按预期返回筛选集,但“我的对象”将数据存储在类型为dynamic的成员中,请参见以下示例: public class Data { public Data(string name, dynamic value) { this.Name =

我尝试使用动态linq查询从对象集合(linq to object)检索IEnumerable,集合中的每个对象都有一个内部集合,其中包含另一组存储数据的对象,这些值通过外部集合的索引器访问

使用强类型对象时,动态linq查询将按预期返回筛选集,但“我的对象”将数据存储在类型为dynamic的成员中,请参见以下示例:

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"]);
    }
公共类数据
{
公共数据(字符串名称、动态值)
{
this.Name=Name;
这个。值=值;
}
公共字符串名称{get;set;}
公共动态值{get;set;}
}
公共类数据项:IEnumerable
{
私人收藏清单;
公共数据项()
{u collection=new List();}
公共动态此[字符串名称]
{
得到
{
数据d;
if((d=_collection.FirstOrDefault(i=>i.Name==Name))==null)
返回(空);
回报率(d值);
}
}
公共作废添加(数据)
{{u collection.Add(data);}
公共IEnumerator GetEnumerator()
{
返回_collection.GetEnumerator();
}
}
公共课程
{
公共无效示例()
{
列表存储库=新列表(){
新数据项(){
新数据(“姓名”、“迈克”),
新数据(“年龄”,25岁),
新数据(“出生日期”,新日期时间(1987年1月5日))
},
新数据项(){
新数据(“姓名”、“史蒂夫”),
新数据(“年龄”,30岁),
新数据(“出生日期”,新日期时间(1982年1月10日))
}
};
IEnumerable result=repository.AsQueryable()。其中(“it[\“Age\”]==30”);
if(result.Count()==1)
Console.WriteLine(result.Single()[“Name”]);
}
运行上述示例时,我得到:运算符“==”与操作数类型“Object”和“Int32”不兼容。

动态成员是否与动态Linq查询不兼容?或者是否有另一种构造表达式的方法,可以在处理动态类型的成员时正确计算

非常感谢你的帮助

动态成员是否与动态Linq查询不兼容?或者是否有另一种构造表达式的方法,可以在处理动态类型的成员时正确计算

两者都可以协同工作。只需在进行类似的比较之前将其转换为Int32即可:

IEnumerable<DataItem> result = 
           repository.AsQueryable<DataItem>().Where("Int32(it[\"Age\"]) == 30");
IEnumerable结果=
repository.AsQueryable().Where(“Int32(it[\“Age\”])==30”);
<> > >编辑1:< /强>,已经说过,与LINQ相关联的动态绑定的使用一般受到限制,因为表达式树中不允许动态操作。请考虑以下LINQ到对象查询:

IEnumerable<DataItem> result = repository.AsQueryable().
                                                  Where(d => d["Age"] == 30);
IEnumerable result=repository.AsQueryable()。
式中(d=>d[“年龄”]==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", "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...)
//变体1:始终使用字符串
public void DynamicQueryExample(字符串属性,动态值)
{
列表存储库=新列表(){
新数据项(){
新数据(“姓名”、“迈克”),
新数据(“年龄”,25岁),
新数据(“出生日期”,新日期时间(1987年1月5日))
},
新数据项(){
新数据(“姓名”、“史蒂夫”),
新数据(“年龄”,30岁),
新数据(“出生日期”,新日期时间(1982年1月10日))
}
};
//始终使用字符串比较
string predicate=“it[\”{0}\]”。ToString()==\“{1}\”;
谓词=String.Format(where子句,属性,val.ToString());
var result=repository.AsQueryable().Where(谓词);
if(result.Count()==1)
Console.WriteLine(result.Single()[“Name”]);
}
程序p=新程序();
p、 DynamicQueryExample(“年龄”,30岁);//打印“史蒂夫”
p、 DynamicQueryExample(“生日”,新的日期时间(1982年1月10日));//打印“史蒂夫”
p、 DynamicQueryExample(“姓名”、“迈克”);//打印“史蒂夫”(不,只是开玩笑……)
或:

//变量2:在运行时检测类型。
public void DynamicQueryExample(字符串属性,字符串值)
{
列表存储库=新列表(){
新数据项(){
新数据(“姓名”、“迈克”),
新数据(“年龄”,25岁),
新数据(“出生日期”,新日期时间(1987年1月5日))
},
新数据项(){
新数据(“姓名”、“史蒂夫”),
新数据(“年龄”,30岁),
新数据(“出生日期”,新日期时间(1982年1月10日))
}
};
字符串whereClause=“{0}(它[\“{1}\”])=={2}”;
//在运行时发现类型(并进行相应转换)
Type Type=repository.First()[property].GetType();
字符串stype=type.ToString();
stype=stype.Substring(stype.LastIndexOf('.')+1);
if(type.Equals(typeof(string))){
//需要用“”包围格式化指令
whereClause=whereClause.Replace(“{2}”,“\“{2}\”);
}
字符串谓词=string.Format(whereClause,stype,property,val);
var result=repository.AsQueryable().Where(谓词);
if(result.Count()==1)
Console.WriteLine(result.Single()[“Name”]);
}
var p=新程序();
p、 动态查询示例(“年龄”、“30”);
p、 DynamicQueryExample(“生日”、“日期时间(1982年1月10日)”);
p、 DynamicQueryExample(“姓名”、“迈克”);
你试过
它[\“年龄\]”等于(对象(30))

以便:

IEnumerable<DataItem> result = 
    repository.AsQueryable<DataItem>().Where("it[\"Age\"].Equals(object(30))");
IEnumerable结果=
repository.AsQueryable().Where(“它[\
IEnumerable<DataItem> result = 
    repository.AsQueryable<DataItem>().Where("it[\"Age\"].Equals(object(30))");
IEnumerable<DataItem> result = repository.AsQueryable<DataItem>().Where("it[\"Age\"].ToString() == \"30\"");