我有两个实体实现的接口:
public interface IFilterable
{
AnotherEntity AnotherEntity { get; }
}
public partial class Session : IFilterable
{
//Body defined externally by EF auto-generated code
}
public partial class Camera : IFilterable
{
//Body defined externally by EF auto-generated code
}
对于大多数数据调用,我还有一个在它们之间共享的where子句:
session => session.AnotherEntity.Started > DateTime.Now
这不是实际的表达方式,但这或多或少都是如此。为了防止自己重复这个,我写了这个辅助方法:
private Expression<Func<TFilterable, bool>> GetFilterClause<TFilterable>(DateTime dateTime)
where TFilterable : IFilterable
{
return filterable => filterable.AnotherEntity.Started > dateTime;
}
这样我就可以在我的数据请求中重用这个表达式:
public List<ReturnEntity> GetReturnEntities(DateTime dateTime)
{
var clause = GetFilterClause<Session>(dateTime);
return Get(clause)
//More query generation
}
问题是我遇到了运行时错误:
无法将类型“DataWarehouse.Session”强制转换为“DataWarehouse.Entities.IFilterable”。 LINQ to Entities仅支持转换EDM原语或枚举类型。
但如果我用where TFilterable : IFilterable
替换where TFilterable : Session
子句,它就可以了。我认为泛型类型签名是在编译时生成的,因此已经有IFilterable
的每个实现的定义。看起来情况并非如此。有什么方法可以解决这个问题,还是我被迫为每个实体创建一个过滤子句辅助方法?现在它对2个实体来说并不算太糟糕,但我可以想象将来需要将这个过滤器应用于3个或更多,并保持许多相似的条款将是一场噩梦。