【问题标题】:Access Linq result contained in a dynamic class访问动态类中包含的 Linq 结果
【发布时间】:2009-09-01 20:00:18
【问题描述】:

我正在使用 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 对象中获取 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));

也许有人知道更清洁的方法?

【问题讨论】:

    标签: c# linq linq-to-sql dynamic-linq


    【解决方案1】:

    Linq 使用延迟执行的方法来获取数据。 Deferred execution 表示表达式的计算被延迟到实际需要它的实现值。

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

    希望这有帮助。

    【讨论】:

    • 问题在于 Dynamic Linq Select 扩展方法返回 IQueryable 对象而不是 IQueryable 对象。结果是没有任何方便的 ToList 等方法可用。虽然我想最终这些方法肯定只是在引擎盖下使用 IEnumberator。
    【解决方案2】:

    解决方案的动态方面迫使您使用反射。您可以使用 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);
    }
    

    没有创建函数来为您完成其中的一些工作,没有太多需要改进的地方。编译器只是不知道对象中有什么,因为它是动态的。因此,非反射代码的所有优点都是不可用的。

    【讨论】:

      【解决方案3】:

      解决办法是:

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

      【讨论】:

        猜你喜欢
        • 2015-11-04
        • 1970-01-01
        • 1970-01-01
        • 2014-09-01
        • 2021-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多