Я использую DbLinq, который должен быть эквивалентом Linq2SQL для этого вопроса. Мне нужно создать запрос Linq2SQL, где я указываю столбцы, которые я хочу вернуть во время выполнения. Я могу добиться этого, используя методы расширения Dynamic 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 находится в представлении результатов. Проблема в том, что я не могу понять, как получить значение номера телефона из объекта queryResult? Тип запроса:
QueryProvider<DynamicClass1>
Редактировать: я нашел способ сделать это, но это кажется очень грубым.
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));
Возможно, кто-то знает более чистый способ?
Решение было:
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();
Динамические аспекты вашего решения заставляют вас использовать рефлексию. Вы можете использовать свойство «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);
}
Если не считать создания функций для выполнения некоторых из этих работ для вас, не так много улучшений. Компилятор просто не знает, что находится в объекте, так как он динамический. Так что вся прелесть неотражающего кода недоступна.