我有一些实体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
。有没有办法解决这个问题?
答案 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)}