Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 186
  • Last Modified:

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

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
John Bolter
Asked:
John Bolter
  • 2
1 Solution
 
AndyAinscowCommented:
>>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
 
John BolterAuthor Commented:
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
 
käµfm³d 👽Commented:
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
 
John BolterAuthor Commented:
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

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now