?
Solved

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

Posted on 2014-07-26
4
Medium Priority
?
180 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 2000 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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
Suggested Courses

762 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