Solved

Ideas to help querying a List<sometype> for key value pairs

Posted on 2014-07-26
4
173 Views
Last Modified: 2016-02-16
What I want is to allow the user to enter a list of search criteria such as

a) Job = "President"
b) Age = 52
c) Job = "President" AND (Age >= 50 AND < 55)
d) Sex = "Male" AND (Age >= 50 AND < 55)
e) Sex = "Male"
f) (Job = "President" AND (Age >= 50 AND < 55)) OR (Job = "Actor")

and retrieve when each query is executed for (example code where Clinton etc are created is below)

a) William Clinton, Barack Obama and Ronald Reagan
b) Tom Cruise and Barack Obama
c) Barack Obama
d) Tom Cruise and Barack Obama
e) Tom Cruise, Barack Obama, Ronald Reagan, and William Clinton
f) Tom Cruise, Barack Obama and Ronald Reagan

The selection criteria is to be entered as free text, eg. the user will enter '(Job = "President" AND (Age >= 50 AND < 55)) OR (Job = "Actor")'

So I am sort of wanting an SQL thing for querying a list of people from a List<Person>. Does anyone have any idea how I can do this without using an SQL database and just using .Net (version 4). Can I do this with LINQ and somehow on the fly compile my query to execute against List<Person> like shown here LinqCompileExample

After searching around, someone else has asked the same question here LinqFromText and there is an answer, but not enough detail unfortunately for me to see how to do what I want to do.

The reason I don't want to use SQL is because I don't have an SQL database and I am learning C# and not SQL at the moment.

My example code is shown below.

Thank you

using System;
using System.Collections.Generic;

namespace ConsoleApplication3
{
    public class Person
    {
        public String Forename {get; set;}
        public String Surname { get; set; }
        public List<KeyValuePair<String, Object>> Attributes { get; set; }
    }

    public class Program
    {
        List<Person> people = new List<Person>();

        public Program()
        {
            Person obama = new Person();
            obama.Forename = "Barack";
            obama.Surname = "Obama";
            obama.Attributes = new List<KeyValuePair<String, Object>>();
            obama.Attributes.Add(new KeyValuePair<String, Object>("Job", "President"));
            obama.Attributes.Add(new KeyValuePair<String, Object>("Sex", "Male"));
            obama.Attributes.Add(new KeyValuePair<String, Object>("Nationality", "American"));
            obama.Attributes.Add(new KeyValuePair<String, Object>("Age", 52));
            people.Add(obama);

            Person ronaldReagan = new Person();
            ronaldReagan.Forename = "Ronald";
            ronaldReagan.Surname = "Reagan";
            ronaldReagan.Attributes = new List<KeyValuePair<String, Object>>();
            ronaldReagan.Attributes.Add(new KeyValuePair<String, Object>("Job", "President"));
            ronaldReagan.Attributes.Add(new KeyValuePair<String, Object>("Job", "Actor"));
            ronaldReagan.Attributes.Add(new KeyValuePair<String, Object>("Sex", "Male"));
            ronaldReagan.Attributes.Add(new KeyValuePair<String, Object>("Nationality", "American"));
            people.Add(ronaldReagan);

            Person tomCruise = new Person();
            tomCruise.Forename = "Tom";
            tomCruise.Surname = "Cruise";
            tomCruise.Attributes = new List<KeyValuePair<String, Object>>();
            tomCruise.Attributes.Add(new KeyValuePair<String, Object>("Job", "Actor"));
            tomCruise.Attributes.Add(new KeyValuePair<String, Object>("Sex", "Male"));
            tomCruise.Attributes.Add(new KeyValuePair<String, Object>("Age", 52));
            people.Add(tomCruise);

            Person clinton = new Person();
            clinton.Forename = "William";
            clinton.Surname = "Clinton";
            clinton.Attributes = new List<KeyValuePair<String, Object>>();
            clinton.Attributes.Add(new KeyValuePair<String, Object>("Job", "President"));
            clinton.Attributes.Add(new KeyValuePair<String, Object>("Sex", "Male"));
            clinton.Attributes.Add(new KeyValuePair<String, Object>("Age", 67));
            people.Add(clinton);
        }

        public void Run()
        {
            //code goes here
            // SELECT Job = "President" and retrieve William Clinton, Barack Obama and Ronald Reagan
            // SELECT Age = 52 and retrieve Tom Cruise and Barack Obama
            // SELECT Job = "President" AND (Age >= 50 AND < 55) and retrieve Barack Obama
            // SELECT Sex = "Male" AND (Age >= 50 AND < 55) and retrieve Tom Cruise and Barack Obama
            // SELECT Sex = "Male" and retrieve Tom Cruise, Barack Obama, Ronald Reagan, and William Clinton
            // SELECT (Job = "President" AND (Age >= 50 AND < 55)) OR (Job = "Actor") and retrieve Tom Cruise, Barack Obama and Ronald Reagan
        }

        static void Main(string[] args)
        {
            Program program = new Program();
            program.Run();
        }
    }
}

Open in new window

0
Comment
Question by:John Bolter
  • 2
4 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 40222939
>>The selection criteria is to be entered as free text

That will make it pretty difficult for a beginner to code.  (What do you do if something is mistyped, eg. Job = preident).
0
 

Author Comment

by:John Bolter
ID: 40222978
Hi, thanks.

I'm pretty good with Ruby and Python, just learning C#, so it's going to be hard but I want to learn all this before I start University in September.

If the user types preident and not president, too bad! It should search for preident and return 0 hits. If the user makes a typo and types in Job >ex "President", too bad, it should return 0 hits because the query is junk.

I want to believe I can do this with dynamically created LINQ but even if I can't, I can't see how to do this in C# is not using a database and dynamically constructing SQL.

Thanks though
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 500 total points
ID: 40223449
I want to believe I can do this with dynamically created LINQ...
Well, LINQ is composable, so you can certainly build the query up as you go, but the problem you have--as Andy alluded to--is that you need a parser for the "free-form" input you are looking to receive from the user. You could write your own parser from scratch (no simple task), or you could try to locate a parser that someone else has built, which might allow you to dictate the grammar you expect to have.

Here's a parser you might try:  https://github.com/sprache/Sprache

I can't say that I've used it myself, but it looks interesting.
0
 

Author Closing Comment

by:John Bolter
ID: 40260250
Thank you. I have written some horrible code but I will have to look at it when I am a better programmer. It is only test code to help me learn anyway.
Thanks for your comment
0

Featured Post

How our DevOps Teams Maximize Uptime

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us. Read the use case whitepaper.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question