演员在哪里?LINQ to Entities仅支持转换实体数据模型基元类型

wes*_*ton 23 c# entity-framework

我有许多实体框架表,我IHistoricEntity使用他们的parital类支持一个接口.IHistoricEntity拥有ActiveTo Datetime?财产.

// Auto generated LINQ to Entities domain service:
[EnableClientAccess()]
public partial class ProductService : LinqToEntitiesDomainService<ProductDBEntities>
{
    public IQueryable<ANALYSIS_CODES> GetANALYSIS_CODES()
    {
        return this.ObjectContext.ANALYSIS_CODES;
    }
 ...
}

// My Partial class to add interface
public partial class ANALYSIS_CODES : IHistoricEntity
{}
Run Code Online (Sandbox Code Playgroud)

我试图将这个工作代码重构为一个方法:

List<ANALYSIS_CODE> filtered = (from rec in ps.GetANALYSIS_CODES() where rec.ActiveTo == null select rec).ToList()
Run Code Online (Sandbox Code Playgroud)

像这样:

private List<T> Filter<T>(IQueryable<T> queryable) where T : IHistoricEntity
{
    return (from rec in queryable where rec.ActiveTo == null select rec).ToList();
}

// called like this:
List<ANALYSIS_CODE> filtered = Filter(ps.GetANALYSIS_CODES());
Run Code Online (Sandbox Code Playgroud)

这给出了以下异常ToList:

无法将"ANALYSIS_CODES"类型强制转换为"IHistoricEntity"类型.LINQ to Entities仅支持转换实体数据模型基元类型.

但是我在哪里要求它投射到IHistoricEntity?我已经说过T必须支持IHistoricEntity.

dev*_*vio 45

rec.ActiveTo指的是在您的界面中定义的属性.因此LINQ的需要投recIHistoricEntity能够访问该属性之前.

不要被引发的异常所迷惑.ToList():Linq查询仅在需要记录时进行评估和执行,在这种情况下,当要将集合转换为a时List<>.

更新:我验证了@ hvd的评论,实际上,添加一个where T: class子句会更改Linq表达式

System.Collections.Generic.List`1[MyType]
    .Where(x => (Convert(x).ActiveTo == Convert(null)))
Run Code Online (Sandbox Code Playgroud)

System.Collections.Generic.List`1[MyType]
    .Where(x => (x.ActiveTo == Convert(null)))
Run Code Online (Sandbox Code Playgroud)

  • "因此Linq需要在能够访问该属性之前将`rec`转换为`IHistoricEntity`." - 几乎,但不完全.通过在泛型参数上包含`class`约束来避免该要求.当事先知道类型是引用类型时,转换为"IHistoricEntity"是无操作并且不包括在内.(演员阵容可能是拳击操作,因为`T`可能是一个结构.) (23认同)
  • @hvd很好,感谢你们两个,"T:class,IHistoricEntity`做了诀窍.启动非常有意义! (2认同)