我的数据模型中的类实现了一个接口:
public class SomeType : ISomeInterface
public interface ISomeInterface
在我的WCF查询拦截器中,我想使用一个公共Expression
,以便我可以在多种类型上使用相同的过滤逻辑:
[QueryInterceptor("SomeType")]
public Expression<Func<SomeType, bool>> SomeTypeInterceptor()
{
// Return CommonFilter() or extend it with logic unique to SomeType
}
private Expression<Func<ISomeInterface, bool>> CommonFilter()
{
// Use ISomeInterface methods and properties to build expression
// ...
}
问题是让Expression<Func<SomeType, bool>>
与Expression<Func<ISomeInterface, bool>>
相处。
尝试#1
只返回公共表达式不会编译:
[QueryInterceptor("SomeType")]
public Expression<Func<SomeType, bool>> SomeTypeInterceptor()
{
return CommonFilter();
}
错误:
无法隐式将
System.Linq.Expressions.Expression<System.Func<ISomeInterface, bool>>
类型转换为System.Linq.Expressions.Expression<System.Func<SomeType, bool>>
尝试#2
在查询拦截器定义中使用接口:
[QueryInterceptor("SomeType")]
public Expression<Func<ISomeInterface, bool>> SomeTypeInterceptor()
编译,但WCF不喜欢这样,向客户端返回错误:
返回方法的类型&#39; SomeTypeInterceptor&#39;在类型&#39;数据服务&#39;属于
System.Linq.Expressions.Expression<System.Func<ISomeInterface, System.Boolean>>
类型,但查询拦截器需要可分配给System.Linq.Expressions.Expression<System.Func<SomeType, System.Boolean>>
的类型。
尝试#3
查看问题How can I cast an expression from type interface, to an specific type和C# How to convert an Expression<Func<SomeType>>
to an Expression<Func<OtherType>>
,我尝试实施this answer:
[QueryInterceptor("SomeType")]
public Expression<Func<SomeType, bool>> SomeTypeInterceptor()
{
Expression<Func<SomeType, bool>> someTypeExpression =
someType => CommonFilter().Compile().Invoke(someType);
return someTypeExpression;
}
但是现在LINQ to Entities不喜欢这样,返回错误:
LINQ to Entities无法识别方法&#39;布尔调用(ISomeInterface)&#39;方法,并且此方法无法转换为商店表达式。
有没有办法在WCF查询拦截器中使用通用逻辑?
答案 0 :(得分:2)
使用CommonFilter
方法对泛型类型参数加上class
约束(LINQ to Entities所需)的必需接口约束进行泛型化:
private Expression<Func<T, bool>> CommonFilter<T>()
where T : class, ISomeInterface
{
// Use ISomeInterface methods and properties to build expression
// ...
}
然后使用 Attempt#1 的稍微修改版本(它会编译):
[QueryInterceptor("SomeType")]
public Expression<Func<SomeType, bool>> SomeTypeInterceptor()
{
return CommonFilter<SomeType>();
}