anivas
anivas

Reputation: 6557

Generic property getter in Linq

I having a hierarchy collection object where I am trying to retrieve the last level object's property in Linq. I dont want to write a get method for every property. Not sure how to achieve it through selector

Class Test {
    public int ID { get; set; }
    public int PopertyA { get; set; }
    public string PopertyB { get; set; }
              ...Many more properties

}

public static TResult GetTest(hierarchyObject, int ID, Func<TSource, TResult> selector)
{
    return (from level1 in hierarchyObject.Level1
            from test in level1.Test
            where test.ID.Equals(ID)
            select selector).First();
}

This dint work. Currently I have made the method to return the test object and accessing the properties in the calling method. But wanted to know if I can implement a generic property getter.

Edit:

Class Hierarcy{
  public IList<Level1> level1;
}

Class Level1 {
public IList<Test> test;
}

Given a hierachy object and test.ID, I want to retrieve any property of Test.

Upvotes: 0

Views: 617

Answers (3)

vgru
vgru

Reputation: 51264

It depends on what you want to do with your property. To avoid repeating the entire LINQ query for each and every property you are interested in, it would be better to get the Test object first, and then check its individual properties:

class Hierarcy
{
   public IList<Level1> Level1;
   public Test GetTest(int ID)
   {
       return this
          .Level1
          .SelectMany(level => level.Test)
          .Where(test => test.ID == ID)
          .First();
   }
}

Once you get the Test class, you have all its properties:

Test t = myHierarchy.GetTest(someId);

// do something
int i = test.PropertyA;
string s = text.PropertyB;

If you are interested in getting a value of a property dynamically, using its name only, you can do it using Reflection:

Test t = myHierarchy.GetTest(someId);

// this will print all properties and their values
foreach (PropertyInfo pi in t.GetType().GetProperties())
{
    Console.WriteLine("Name:{0}, Value:{1}",
       pi.Name,
       pi.GetValue(pi, null));
}

In both examples, actual query is executed only once, which can be significant if there are lots of objects in your collections.

Upvotes: 1

Niki
Niki

Reputation: 15867

I guess you might want something like this:

public static TResult GetTest(hierarchyObject, int ID, Func<Test, TResult> selector)
{
    return (from level1 in hierarchyObject.Level1
            from test in level1.Test
            where test.ID.Equals(ID)
            select selector(test)).First();
}

Upvotes: 1

Euphoric
Euphoric

Reputation: 12849

You must use method chain. You cant use query expression. At least for Select part. Rest can remain as query expression.

hiearchyObject.Level1.SelectMany(x=>x.Test).Where(test=>test.ID.Equals(ID)).Select(selector).First();

Dont have PC to test it now.

Also in method, you should either declare whole method as generic acording to selector (same generic parameters) or use public static TResult GetTest<TResult> (.. , Func<Test, TResult> selector)

Upvotes: 0

Related Questions