Solved

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

Posted on 2014-07-26
4
174 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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

726 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