我正在使用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值位于Results View中。问题是我无法弄清楚如何从queryResult对象获取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));
也许有人知道更清洁的方式?
答案 0 :(得分:0)
Linq使用延迟执行方法来获取数据。 Deferred execution表示表达式的评估被延迟,直到实际需要实现的值。
在您的情况下,queryResult是一个IEnumerable对象,这意味着尚未实际评估任何数据。您可以通过调用result.ToList()或result.ToDictionary()或任何其他将返回具有非IEnumerable数据类型的对象的方法来评估queryResult对象。
希望这有用。
答案 1 :(得分:0)
解决方案的动态方面迫使您使用反射。您可以使用IQueryable的“ElementType”属性,而不是获取第一个项目并读取它的类型。然后,像这样的循环可能会更好:
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);
}
如果没有创建功能来为您完成这项工作,那么就没有什么可以改进的了。编译器只是不知道对象中的内容,因为它是动态的。因此,非反射代码的所有优点都不可用。
答案 2 :(得分: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();