带有表达式的泛型类会在Linq-To-Entities中引发错误

时间:2016-04-07 09:57:19

标签: c# entity-framework linq generics

我有一些实体Logging来实现ILogging,假设它只有两个属性:

public partial class Logging : ILogging
{
    public int ID {get; set;}
    public string Name {get; set;}
}
public interface ILogging { int ID {get; set;} }

我最初有一个静态类Logging.Q,其中包含静态Expression<Func<Logging,bool>>字段,但现在我希望能够编写ILogging的表达式,如果它们只需要ID

public partial class Logging
{
    public static Q<T> where T : ILogging
    {
        public static Expression<Func<T,bool>> IDOne = l => l.ID == 1;
    }
}

当我打电话给这样的表达时:

var log = ctx.Logging.Where(Logging.Q<Logging>.IDOne).FirstOrDefault();

我得到了臭名昭着的“linq to entities only supports ...”:

  

无法将“Entities.Logging”类型转换为“Entities.ILogging”类型。 LINQ to Entities仅支持转换EDM原语或枚举类型。

但我不知道为什么。我在类Q上定义了我的泛型类型,因此运行时应该知道我正在处理Logging而不是ILogging。有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:2)

Sounds like a C# compiler bug or defect in expression trees.

When the constraint is where T : ILogging or where T : struct, ILogging, the generated expression is {l => (Convert(l).ID == 1)}, i.e. includes a cast (note the Convert) which in turn causes the notorious EF exception.

However, putting a class constraint removes the cast and EF is just happy:

where T : class, ILogging results in {l => (l.ID == 1)}