Use a dynamic class to access a Linq result.

c# dynamic-linq linq linq-to-sql

Question

I'm using DbLinq which should be the equivalent of Linq2SQL for this question. I'm need to generate a Linq2SQL query where I specify the columns I want returned at runtime. I can achieve that using the Dynamic Linq extension methods but I can't work out how to extract the result.

string someProperty = "phonenumber";
string id = "1234";

Table<MyClass> table = context.GetTable<MyClass>();
var queryResult = (from item in table where item.Id == id select item).Select("new (" + someProperty + ")");

The Linq expression generates the proper SQL of:

select phonenumber from mytable where id = '1234'

And in the debugger I can see the phonenumber value is sitting there in the Results View. The problem is I can't work out how to get the phonenumber value from the queryResult object? The type of queryResult is:

QueryProvider<DynamicClass1>

Edit: I discovered a way to do it but it seems very crude.

IEnumerator result = (from item in table where item.Id == id select item).Select("new (" + someProperty + ")").GetEnumerator();
result.MoveNext();
var resultObj = result.Current;
PropertyInfo resultProperty = resultObj.GetType().GetProperty(someProperty);
Console.WriteLine(resultProperty.GetValue(resultObj, null));

Perhaps someone knows a cleaner way?

1
0
6/19/2009 2:45:24 PM

Accepted Answer

The solution was:

string someProperty = "phonenumber";
PropertyInfo property = typeof(T).GetProperty(propertyName);
string id = "1234";
Table<MyClass> table = context.GetTable<MyClass>();
Expression<Func<T, Object>> mySelect = DynamicExpression.ParseLambda<T, Object>(property.Name);
var query = (from asset in table where asset.Id == id select asset).Select(mySelect);
return query.FirstOrDefault();
0
9/1/2009 12:00:18 PM

Popular Answer

The dynamic aspects of your solution force you to use reflection. You could use the "ElementType" property of the IQueryable rather than getting the first item and reading it's type. Then, a loop like this may be better:

var result = (from item in table where item.Id == id select item).Select("new (" + someProperty + ")");
PropertyInfo resultProperty = result.ElementType.GetProperty(someProperty);
foreach (var resultObj in result)
{
    var value = resultProperty.GetValue(resultObj, null);
}

Short of creating functions to do some of this work for you, there isn't much left to improve. The compiler just doesn't know what's in the object, since it's dynamic. So all the niceness of non-reflective code is unavailable.



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