可以通过IQueryable <t> </t>

时间:2011-05-11 13:05:12

标签: linq entity-framework

是否有可能将IQueryable对象转换为IQueryable,其中T是映射实体? (T将是POCO课程。)

提前致谢。

1 个答案:

答案 0 :(得分:9)

只需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`)

但是在您的情况下,您说您正在使用Dynamic LINQ并进行动态投影。考虑这个完全构成的查询:

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

它会产生IQueryable类型的查询。毕竟,您不能将此转换为特定类型IQueryable<T>的查询,T是什么? Dynamic LINQ库的作用是创建一个派生自DynamicCass的类型。您可以转为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,那么我认为你必须获得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,
    });
}