3

I have a linq question (linq to sql). I have the following peice of code which works fine;

       var queryx = (from sa in d1.SampleAttributes
                      where nodeTable.ToList().Distinct().Contains(sa.client_post_code_prefix)
                     select sa.SampleId).Distinct();

Note: nodeTable is of type IQueryable

However, I would like to change this so that the column name within the contain method can be decided at runtime. I determine the column name from another query dependent on certain user filters being applied and would ideally like something with the follwing logic;

//please note that the string I pass into obtain a 'column object' always shares the same name as the column

        var columnWhatever = GetColumnName(string colName);

        var queryx = (from sa in d1.SampleAttributes
                      where nodeTable.ToList().Distinct().Contains(sa.client_post_code_prefix)
                     select sa.SampleId).Distinct();

So far I have been unable to find anything that will allow this and I'm beggining to think that Linq does not allow such logic. Any help would be much appreciated

saj
  • 4,626
  • 2
  • 26
  • 25
  • dup? http://stackoverflow.com/questions/2148309/how-do-i-reference-a-field-in-linq-based-on-a-dynamic-fieldname – Rob Fonseca-Ensor Jan 27 '10 at 16:23
  • @Rob - not necessarily; the first could be answered with reflection, but this may be something else... – Marc Gravell Jan 27 '10 at 16:24
  • 1
    @saj - what is the underlying LINQ implementation here? LINQ-to-Objects? Entity Framework? LINQ-to-SQL? It matters, unfortunately. – Marc Gravell Jan 27 '10 at 16:24
  • What is the type of `nodeTable`? Is this LINQ to SQL or LINQ to objects? – jason Jan 27 '10 at 16:25
  • 1
    By the way, your `where` clause should be `nodeTable.Contains(sa.client_post_code_prefix)`. There's no point in calling `ToList().Distinct()`; it'll just waste time and memory. – SLaks Jan 27 '10 at 16:25
  • thanks for the heads up SLaks, I think I started like you suggest but after trying all sorts ended up with what I put up – saj Jan 27 '10 at 20:49

2 Answers2

3

You might take a look at the Dynamic LINQ library. I posted about it here. Take a look and see if that might help you. Also see Scott Guthrie's post about it here.

Brian Sullivan
  • 27,513
  • 23
  • 77
  • 91
2

If this is LINQ to object you can do this very easily using reflection. To wit:

string colName;
var queryx = (from sa in d1.SampleAttributes
              where nodeTable.Contains(
                                 sa.GetType()
                                   .GetProperty(colName)
                                   .GetValue(sa, null)
                                   .ToString()
                             )
              select sa.SampleId).Distinct();

This is assuming that nodeTable is an IEnumerable<string>.

It would be better to only perform the reflection piece once. Say that the compile-time type of sa is SampleAttribute. Then you could do the following:

string colName;
PropertyInfo info = typeof(SampleAttribute).GetProperty(colName);
Func<SampleAttribute, string> func = sa => info.GetValue(sa, null).ToString();
var queryx = (from sa in d1.SampleAttributes
              where nodeTable.Contains(func(sa))
              select sa.SampleId).Distinct();

If this is LINQ to SQL you can do this easily using System.Linq.Expressions.Expression. If you give a little more detail about the type of nodeTable I can walk you through this.

jason
  • 236,483
  • 35
  • 423
  • 525
  • Hi Jason this is linq to sql. I'm assuming your answer would not apply to linq to sql although on first sight I can't understand why it would work on linq to object and not on linq to sql. – saj Jan 27 '10 at 20:47
  • And nodeTable is of type IQueryable. Thanks – saj Jan 27 '10 at 20:59