将IQueryable转换为IQueryable<T>

6

是否可以将IQueryable对象转换为IQueryable,其中T是映射实体? (T将是一个POCO类)。

谢谢提前。


2
你如何获取非泛型的 IQueryable - Ladislav Mrnka
我不知道这是否有帮助,但我选择了另一种方式。使用扩展方法,将一个实体的IQueryable转换为一个对象的IQueryable。我在这里写了一篇博客文章:https://webdevschool.iimagine-websolutions.com/book-1-chapter-7-mod-23 - undefined
1个回答

14

只需使用 Cast<T>()。假设它是相同类型的可查询对象。否则,您可以使用OfType<T>()过滤方法来过滤特定类型的项目。

IQueryable query = ...;
IQueryable<MyType> x = query.Cast<MyType>();  // assuming the queryable is of `MyType` objects
IQueryable<MyDerivedType> y = query.OfType<MyDerivedType>(); // filter out objects derived from `MyType` (`MyDerivedType`)

然而,在你的情况下,你说你正在使用动态LINQ并进行动态投影。考虑这个完全虚构的查询:
var query = dc.SomeTable
              .Where("SomeProperty = \"foo\"")
              .Select("new (SomeProperty, AnotherProperty)");

它的查询结果类型为 IQueryable。你不能将其强制转换为特定类型的查询 IQueryable<T>,因为 T 是什么呢?动态 LINQ 库创建了一个从 DynamicClass 派生的类型。你可以将其转换为 IQueryable<DynamicClass> (query.Cast<DynamicClass>()),但是您将无法访问属性,因此这是无意义的。

实际上,在这种情况下,您唯一的好选择是使用 dynamic 访问这些属性。

foreach (dynamic x in query)
{
    string someProperty = x.SomeProperty;
    int anotherProperty = x.AnotherProperty;
    // etc...
}

如果您想将此转换为POCO对象的查询,您需要将转换作为单独的步骤,但使用LINQ to Objects进行。

IEnumerable<SomePoco> query =
    dc.SomeTable
      .Where("SomeProperty = \"foo\"")
      .Select("new (SomeProperty, AnotherProperty)")
      .Cast<DynamicObject>().AsEnumerable().Cast<dynamic>()
      .Select(x => new SomePoco
      {
          SomeProperty = x.SomeProperty,
          AnotherProperty = x.AnotherProperty,
      });

如果必须使用 IQueryable<T>,则首先不应该使用动态投影。

IQueryable<SomePoco> query =
    dc.SomeTable
      .Where("SomeProperty = \"foo\"")
      .Select(x => new SomePoco
      {
          SomeProperty = x.SomeProperty,
          AnotherProperty = x.AnotherProperty,
      });

鉴于LINQ to Entities不支持cast,那么您唯一的选择就是将其拆分成循环以获得POCO对象的强类型集合。

var query = dc.SomeTable
              .Where("SomeProperty = \"foo\"")
              .Select("new (SomeProperty, AnotherProperty)");

var result = new List<SomePoco>();
foreach (dynamic x in query)
{
    result.Add(new SomePoco
    {
        SomeProperty = x.SomeProperty,
        AnotherProperty = x.AnotherProperty,
    });
}

我收到了 System.Exception 错误:不能执行类型转换.. Linq To Entities 仅支持原始类型的强制转换.. - Alex70
我所需要的就是从动态linq到实体开始实现一个IQueryable<T>:步骤1:我有这样的东西-> var query1 = myCtx.Where(..lambda);步骤2:我必须仅选择一些字段(我不能在此处使用lambda),因此: var query2 = query1.Select("myFiled1, myFiled2);通过ScottGu的System.Linq.Dynamic.dll库可以实现步骤2。问题在于:步骤2返回一个IQueryable,而我需要一个IQueryable<T>,其中T是我的POCO类。我无法进行转换...每次转换时都会出现异常。 - Alex70
@Alex:这是你提问时有用的信息。在这种情况下,由于你投射到一个动态类型,技术上你不知道编译时的类型,因此无法将其强制转换为特定类型。但是你可以将其强制转换为DynamicClass,因为这些对象都是从该类型派生的,但是除非使用dynamic变量,否则无法直接访问字段。 - Jeff Mercado
请问,您能给我一个例子吗?我不确定是否理解了您的回答。 - Alex70
@Alex:我已经扩展了我的答案。希望现在更清楚了。 - Jeff Mercado
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接