在c#中的expandoObject列表中搜索 [英] Search in list of expandoObject in c#

查看:113
本文介绍了在c#中的expandoObject列表中搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个动态对象列表,例如:

  var  records = [
{
Id 1
名称 sai
年龄 4
关于 12.02.1991
},
{
Id 2
名称 h jfh
年龄 2
关于 12.02.1991
},
{
Id 3
名称 hello name
年龄 6
关于 hi
},
{
Id 4
名称 1
年龄 9
关于 hello world
}
]



string searchString =Hello ;

我试过类似的东西:

  foreach  var  item  in  records)
{

foreach var 字段 项目)
{
if (field.Value!= null && field.Value.ToString()。IndexOf(query.SearchString,StringComparison.OrdinalIgnoreCase)> = 0
{
count ++;
break ;
}
}
}



我想要在记录中的任何字段都有searchString的记录数。但是我可以使用LINQ查询来写这个吗?



任何帮助都会非常明显。

解决方案

我可以找到解决方案。



  var  records =  new  [] 
{
new
{
Id = 1
Name = sai
年龄= 4
关于= 12.02.1991
},

new
{
Id = 2
Name = hjfh
年龄= < span class =code-string> 2,
关于= 12.02.1991
},

new
{
Id = 3
名称= 你好名字
年龄= 6
关于= hi
},

new
{
Id = 4
Name = 1
年龄= 9
关于= hello world
}
};

int count = records.Count(x = > x.Name .StartsWith( hello)|| x.About.StartsWith( hello));


我在这里看到的是试图使用匿名类型数组,而不是在System.Dynamic库中使用Expando:差别很大!



此外,由于这里的数组元素是匿名类型本身不是可枚举的...即不是数组,例如......你无法迭代每个元素来访问所有内部字段,做你想描述的事情。



当然,您可以遍历一个匿名类型数组,其中您已正确命名每个内部类型,并按名称访问所有类型。这意味着,如果你想解析每个字段,你将需要检查每个字段,如果你有不同类型的字段,那么你可能需要转换类型。



虽然你可以使用某种形式的反射来访问内部字段:[ ^ ],需要非常高级的编程。



此外,如果你想保存(序列化)一个匿名类型,例如,对于XML,你将不得不使用非常奇特的代码:[ ^ ]。



由于很多原因,包括上述内容,我建议你使用匿名类型...除非你是一个非常高级的.NET程序员,并愿意在计算资源和时间的使用方面支付可能的高价格。



Visual Studio 2013的MSDN:匿名类型提供了一种方便的方法,可以将一组只读属性封装到单个对象中,而无需先显式定义类型。类型名称由编译器生成,在源代码级别不可用。每个属性的类型由编译器推断。

[ ^ ]。



请注意,匿名类型是不可变的(由只读术语暗示)另请注意,编译器在处理匿名类型数组时会进行内部类型检查:请参阅最后的注释。



首先,让我们得到任何东西你正在尝试编译。



这是一个匿名类型数组在C#中的样子:

  var  records =  new  [] 
{
new
{
Id = 1
Name = sai
年龄= 4
Abou t = 12.02.1991
},

< span class =code-keyword> new
{
Id = 2
Name = hjfh
年龄= 2
关于= 12.02。 1991
},

new
{
Id = 3
Name = hello name
年龄= 6
关于= hi
},


{
Id = 4
Name = 1
年龄= 9
关于= hello world
}
};

请注意如果你在这里改变匿名类型的一个字段的类型;例如:

  new  
{
Id = 4
Name = 1 ;
年龄= 9
关于= hello world
}

这里我们将Name属性的Type更改为Int来自字符串。



在此更改之后,这将无法编译:编译器尝试构建内部类型序列,通过从内部类型推断内部类型来强制执行类型一致性Type结构,因此它无法处理Type声明中的任何变化!这种错误可能会让人感到困惑。


 records.Cast< ExpandoObject>()
.Where(x => x .Any(y => y.Value!= null&& y.Value.ToString()。IndexOf(SearchString,StringComparison.OrdinalIgnoreCase)> = 0 ))
.Count();


Suppose I have a List of dynamic objects like:

var records = [
  {
    "Id": 1,
    "Name": "sai",
    "Age": "4",
    "About": "12.02.1991"
  },
{
    "Id": 2,
    "Name": "hjfh",
    "Age": "2",
    "About": "12.02.1991"
  },
{
    "Id": 3,
    "Name": "hello name",
    "Age": "6",
    "About": "hi"
  },
{
    "Id": 4,
    "Name": 1,
    "Age": "9",
    "About": "hello world"
  }
]


string searchString = "Hello";
I tried something like:

foreach (var item in records )
{

    foreach (var field in item)
    {
        if (field.Value != null && field.Value.ToString().IndexOf(query.SearchString, StringComparison.OrdinalIgnoreCase) >= 0)
        {
            count++;
            break;
        }
    }
}


I want the count of records which has searchString at any field in the record. but can I write this using a LINQ query?

Any help would be greatly appreciable.

解决方案

I could figure out the solution for this.

var records = new[]
{
    new
    {
        Id = 1,
        Name = "sai",
        Age = "4",
        About = "12.02.1991"
    },

    new
    {
        Id = 2,
        Name = "hjfh",
        Age = "2",
        About = "12.02.1991"
    },

    new
    {
        Id = 3,
        Name = "hello name",
        Age = "6",
        About = "hi"
    },

    new
    {
        Id = 4,
        Name = "1",
        Age = "9",
        About = "hello world"
    }
};

int count = records.Count(x => x.Name.StartsWith("hello") || x.About.StartsWith("hello"));


What I see here is an attempt to use an Array of Anonymous Types, not a use of the Expando in the System.Dynamic Library: big difference !

Further, since your Array elements here are Anonymous Types which are not themselves Enumerable ... i.e. not Arrays, for example ... there's no way you can iterate over each element to access all the internal Fields, to do what you describe you want to do.

You can, of course, iterate over an Array of Anonymous Types where you have properly named each internal Type, and access all Types by their Name. That means, if you wish to parse every field you will have to check every field, and if you have fields of different Types, then you may have to do conversion of Types.

While you could use some form of Reflection to access the internal Fields: [^], that requires very advanced programming.

Further, if you wish to save (serialize) an Anonymous Type, to XML for example, you are going to have to use quite exotic code: [^].

For many reasons, including the above, I'd advise you not to use Anonymous Types ... unless you are a very advanced .NET programmer, and willing to pay a possibly high price in terms of use of computational resources and time.

MSDN for Visual Studio 2013:

"Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first. The type name is generated by the compiler and is not available at the source code level. The type of each property is inferred by the compiler."

[^].

Note that Anonymous Types are "immutable"(implied by the term read-only). Also note that the compiler while processing an Array of Anonymous Types will do internal type-checking: see the note at the end here.

First, let's get whatever you are trying to do to compile.

This is what an Array of Anonymous Types would look like in C#:

var records = new[]
{
    new
    {
        Id = 1,
        Name = "sai",
        Age = "4",
        About = "12.02.1991"
    },

    new
    {
        Id = 2,
        Name = "hjfh",
        Age = "2",
        About = "12.02.1991"
    },

    new
    {
        Id = 3,
        Name = "hello name",
        Age = "6",
        About = "hi"
    },

    new
    {
        Id = 4,
        Name = "1",
        Age = "9",
        About = "hello world"
    }
};

Note that if you change the Type of one of the Fields of the Anonymous Type here; for example:

new
{
    Id = 4,
    Name = 1;
    Age = "9",
    About = "hello world"
}

Here we changed the Type of the Name Property to an Int from a String.

After this change, this will not compile: the compiler, trying to construct a sequence of internal Types, enforces Type consistency by inferring the internal Types from the Type structure, so it can't handle any variance in Type declaration ! This kind of bug can be quite confusing to encounter.


records.Cast<ExpandoObject>()
       .Where(x => x.Any(y => y.Value != null && y.Value.ToString().IndexOf(SearchString, StringComparison.OrdinalIgnoreCase) >= 0))
       .Count();


这篇关于在c#中的expandoObject列表中搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆