访问包含在动态类中的Linq结果

Asked
Viewd2246

0

我正在使用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'
 

在调试器中,我可以在结果视图中看到电话号码值。问题是我不知道如何从queryResult对象获取电话号码值? 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));
 

也许有人知道更干净的方法?

3 个答案

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使用延迟执行方法来获取数据。 延迟执行意味着表达式的求值被延迟,直到实现为止值是实际需要的。

在您的情况下,queryResult是IEnumerable对象,这意味着尚未实际评估任何数据。您可以通过调用result.ToList()或result.ToDictionary()或任何其他将返回具有非IEnumerable数据类型的对象的方法来评估queryResult对象。

希望这会有所帮助。

  • 存在动态Linq Select扩展方法的问题,该方法返回IQueryable对象而不是IQueryable 对象。其结果是没有方便的ToList等方法可用。尽管我猜想这些方法最终都必须在幕后使用IEnumberator。

    sipwizJune 19, 2009 15:22
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);
}
 

创建函数来为您完成某些工作的时间很短,没有太多需要改进的地方。编译器只是不知道对象中包含什么,因为它是动态的。因此,所有非反射代码都无法使用。