Доступ к результату Linq, содержащемуся в динамическом классе - PullRequest
0 голосов
/ 19 июня 2009

Я использую 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? Тип 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));

Может, кто-нибудь знает более чистый способ?

Ответы [ 3 ]

0 голосов
/ 20 июня 2009

Динамические аспекты вашего решения заставляют вас использовать рефлексию. Вы можете использовать свойство 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);
}

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

0 голосов
/ 01 сентября 2009

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

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 голосов
/ 19 июня 2009

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

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

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

...