使用接口的WCF查询拦截器中的公共过滤逻辑

时间:2017-03-20 16:25:59

标签: c# linq wcf interface expression

我的数据模型中的类实现了一个接口:

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 typeC# 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查询拦截器中使用通用逻辑?

1 个答案:

答案 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>();
}