2009-06-19 2 views
0

Я использую DbLinq, который должен быть эквивалентом Linq2SQL для этого вопроса. Мне нужно создать запрос Linq2SQL, где я укажу столбцы, которые я хочу вернуть во время выполнения. Я могу добиться этого, используя методы расширения Dynamic Linq, но я не могу решить, как извлечь результат.Результат Linq, содержащийся в динамическом классе

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 + ")"); 

Выражение Linq генерирует правильный SQL из:

select phonenumber from mytable where id = '1234' 

И в отладчике я вижу значение PhoneNumber сидит там в представлении результатов. Проблема в том, что я не могу понять, как получить значение phonenumber из объекта queryResult? Тип queryResult является:

QueryProvider<DynamicClass1> 

Edit: Я нашел способ сделать это, но это, кажется, очень сырой.

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)); 

Возможно, кто-то знает более чистый способ?

ответ

0

Решение было:

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

Linq использует метод отложенного выполнения для получения данных. Deferred execution означает, что оценка выражения задерживается до тех пор, пока не будет реализовано его реализованное значение.

В вашем случае queryResult является объектом IEnumerable, что означает, что данные пока не были оценены. Вы можете оценить объект queryResult, вызвав result.ToList() или result.ToDictionary() или любые другие методы, которые возвратят объект с неинеруемыми типами данных.

Надеюсь, это полезно.

+0

Проблема есть динамический Linq Выберите метод расширения возвращает IQueryable объект, а не объект IQueryable . В результате этого нет доступных методов ToList и т. Д. Хотя я предполагаю, что в конечном итоге эти методы должны просто использовать IEnumberator в капоте. – sipwiz

0

Динамические аспекты вашего решения заставляют вас использовать отражение. Вы можете использовать свойство ElementType для IQueryable, а не получать первый элемент и читать его тип. Затем цикл, как это может быть лучше:

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); 
} 

Короткие создания функции, чтобы сделать некоторые из этой работы для вас, там не так много осталось, чтобы улучшить. Компилятор просто не знает, что находится в объекте, так как он динамичен. Таким образом, вся привлекательность неотражающего кода недоступна.

Смежные вопросы