Help with the Dynamic Linq Library

c# dynamic-linq linq

Question

I have the following class:

public class Item
{
    public Dictionary<string, string> Data
    {
        get;
        set;
    }
}

and a list of it:

List<Item> items;

I need to filter and order this list dynamically using SQL-Like strings. The catch is, that I need to order it by the Data dictionary.

For example: Order By Data["lastname"] or Where Data["Name"].StartsWith("a"). I thought to use the dynamic linq library, but is there any way that my clients can write without the Data[]? For example:

Name.StartsWith("abc")

instead of

Data["Name"].StartsWith("abc")

?

1
0
3/28/2010 2:39:19 PM

Popular Answer

This doesn't have anything to do with the Linq Dynamic Query unit. That unit is for when you have actual fields/properties and the names of them will be given to you at runtime. In other words, you have a class like this:

public class Person
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

And you want to be able to write a query like this:

var sortedPeople = people.OrderBy("FirstName");

You are trying to do the exact opposite of this - you have a class that does not have any actual properties, just an attribute dictionary, and you want compile-time safety. You can't have it; there's no way to guarantee that an item will be in the dictionary, especially when the dictionary is public and anyone can add/remove directly from it!

If there's some reason that you must use that specific class design, then you could conceivably write some wrappers as Nick has presented, but I wouldn't even bother - they're not actually providing any encapsulation because the Data dictionary is still wide open to the whole world. Instead, I would just provide a single safe getter method or indexer property and create a few constants (or an enum) with the names of properties you expect to be in there.

public class Item
{
    public Dictionary<string, string> Data { get; set; }

    public string GetValue(string key)
    {
        if (Data == null)
            return null;
        string result;
        Data.TryGetValue(key, out result);
        return result;
    }
}

public class ItemKeys
{
    public const string Name = "Name";
    public const string Foo = "Foo";
}

And so on. Really the ItemKeys isn't that important, the safe GetValue method is what's important, because otherwise you run the risk of a NullReferenceException if Data hasn't been assigned, or a KeyNotFoundException if even one Item instance doesn't have that property. Using the GetValue method here will succeed no matter what:

var myItems = items.OrderBy(i => i.GetValue(ItemKeys.Name));

If you find you're writing a lot of repetitive code for the same attributes, then start worrying about adding shortcut properties or extension methods to the class.

1
3/28/2010 2:54:18 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow