使用接口的WCF查询拦截器中的公共过滤逻辑 [英] Common filtering logic in WCF query interceptors using interface
问题描述
我的数据模型中的类实现了一个接口:
public class SomeType:ISomeInterface
公共接口ISomeInterface
在我的WCF查询拦截器中,我想使用一个常见的
[QueryInterceptor(SomeType )]
public Expression< Func< SomeType,bool>> SomeTypeInterceptor()
{
//返回CommonFilter()或使用SomeType唯一的逻辑扩展它
}
私有表达式< Func< ISomeInterface,bool>>> CommonFilter()
{
//使用ISomeInterface方法和属性来构建表达式
// ...
}
问题是获取 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不喜欢这个,向客户端返回一个错误: p>
类型DataService上的方法SomeTypeInterceptor的返回类型是类型
System.Linq.Expressions.Expression<系统.Func< ISomeInterface,System.Boolean>>
,但可以分配给的类型System.Linq.Expressions.Expression< System.Func< SomeType,System.Boolean>> / code>是查询拦截器所必需的。
尝试#3
查看如何将表达式从类型界面转换为特定类型的问题和 C#如何转换表达式< Func< SomeType>>
到表达式< Func< OtherType>
,我尝试实现这个答案:
[QueryInterceptor(SomeType)]
public Expression< Func< SomeType,bool>>> SomeTypeInterceptor()
{
表达式< Func< SomeType,bool>> someTypeExpression =
someType => 。CommonFilter()编译()调用(SOMETYPE)。
返回someTypeExpression;
}
但现在LINQ to Entities不喜欢这个,返回错误: p>
LINQ to Entities不会识别方法Boolean Invoke(ISomeInterface)方法,并且此方法无法转换为存储表达式。 p>
有没有办法在WCF查询拦截器中使用常见的逻辑?
使通用类型参数加上<$的必需接口约束使 CommonFilter
c $ c> class 约束(LINQ to Entities需要):
private Expression< Func< T,bool>>> CommonFilter< T>()
其中T:class,ISomeInterface
{
//使用ISomeInterface方法和属性来构建表达式
// ...
}
然后使用您的尝试#1 稍微修改版本):
[QueryInterceptor(SomeType)]
public Expression< Func< SomeType,bool>> SomeTypeInterceptor()
{
return CommonFilter< SomeType>();
}
The classes in my data model implement an interface:
public class SomeType : ISomeInterface
public interface ISomeInterface
In my WCF query interceptors, I want to use a common Expression
so that I can use the same filtering logic on multiple types:
[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
// ...
}
The problem is getting the Expression<Func<SomeType, bool>>
to get along with the Expression<Func<ISomeInterface, bool>>
.
Attempt #1
Just returning the common expression does not compile:
[QueryInterceptor("SomeType")]
public Expression<Func<SomeType, bool>> SomeTypeInterceptor()
{
return CommonFilter();
}
with the error:
Cannot implicitly convert type
System.Linq.Expressions.Expression<System.Func<ISomeInterface, bool>>
toSystem.Linq.Expressions.Expression<System.Func<SomeType, bool>>
Attempt #2
Using the interface in the query interceptor definition:
[QueryInterceptor("SomeType")]
public Expression<Func<ISomeInterface, bool>> SomeTypeInterceptor()
compiles, but WCF does not like this, returning an error to the client:
Return type of method 'SomeTypeInterceptor' on type 'DataService' is of type
System.Linq.Expressions.Expression<System.Func<ISomeInterface, System.Boolean>>
but a type assignable toSystem.Linq.Expressions.Expression<System.Func<SomeType, System.Boolean>>
is required for a query interceptor.
Attempt #3
Looking at the questions How can I cast an expression from type interface, to an specific type and C# How to convert an Expression<Func<SomeType>>
to an Expression<Func<OtherType>>
, I tried implementing this answer:
[QueryInterceptor("SomeType")]
public Expression<Func<SomeType, bool>> SomeTypeInterceptor()
{
Expression<Func<SomeType, bool>> someTypeExpression =
someType => CommonFilter().Compile().Invoke(someType);
return someTypeExpression;
}
but now LINQ to Entities does not like this, returning an error:
LINQ to Entities does not recognize the method 'Boolean Invoke(ISomeInterface)' method, and this method cannot be translated into a store expression.
Is there a way to use common logic in WCF query interceptors?
Make the CommonFilter
method generic with required interface constraint on the generic type argument plus class
constraint (needed by LINQ to Entities):
private Expression<Func<T, bool>> CommonFilter<T>()
where T : class, ISomeInterface
{
// Use ISomeInterface methods and properties to build expression
// ...
}
Then use a slightly modified version of your Attempt #1 (which does compile):
[QueryInterceptor("SomeType")]
public Expression<Func<SomeType, bool>> SomeTypeInterceptor()
{
return CommonFilter<SomeType>();
}
这篇关于使用接口的WCF查询拦截器中的公共过滤逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!