Click here to Skip to main content
15,895,084 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Suppose I have a List of dynamic objects like:
C#
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:
C#
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.
Posted
Updated 5-Jan-15 1:14am
v2
Comments
Praveen Kumar Upadhyay 5-Jan-15 7:17am    
One thing is not clear, Can you please reformat the var object. It will give compilation error. What kind of object it is?

I could figure out the solution for this.

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"
    }
};

int count = records.Count(x => x.Name.StartsWith("hello") || x.About.StartsWith("hello"));
 
Share this answer
 
Comments
BillWoodruff 5-Jan-15 8:13am    
+4 This is a useful answer, Praveen, but you do realize that you rewrote and "fixed" the OP's original code which will not compile, as I did ? I noted that you edited the Op's code but did not make it compileable. Also, you changed the Type of some of the Fields.

I am not complaining, my concern is that the OP realize why their code won't work.
Praveen Kumar Upadhyay 5-Jan-15 8:19am    
I don't think that I changed the type of some fields while editing the OP's question, but yes credit goes to you also of making the var object proper. I was a little confuse with the var object, so I was trying the same thing with List<Person> object where Person has all the above property like Id,Name,Age and Acount.

Thanks a lot Bill for Upvoting my answer.
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#:
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:
C#
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.
 
Share this answer
 
v3
Comments
Maciej Los 5-Jan-15 7:15am    
Bill, have a look here: http://stackoverflow.com/questions/27777738/search-in-list-of-expandoobject-in-c-sharp
BillWoodruff 5-Jan-15 8:15am    
Thanks, Maciej, I am in the middle of trying to finish something complex; I'll study your post on SO later, and, if necessary, eat my words :)
BillWoodruff 5-Jan-15 12:04pm    
I'm too burned-out right now to get head back into this question, but will come back tomorrow. cheers, Bill
Maciej Los 6-Jan-15 5:55am    
By posting a link to SO i wanted to say that it's not worth to devote a lot of time to answer this question. Have a nice day!
VB
records.Cast<ExpandoObject>()
       .Where(x => x.Any(y => y.Value != null && y.Value.ToString().IndexOf(SearchString, StringComparison.OrdinalIgnoreCase) >= 0))
       .Count();
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900