C# 没有方法';包含';存在于类型';System.Data.Linq.DataQuery`1[System.Object]';
我正试图建立包含表达式C# 没有方法';包含';存在于类型';System.Data.Linq.DataQuery`1[System.Object]';,c#,linq,dynamic,C#,Linq,Dynamic,我正试图建立包含表达式 private Expression<Func<T, bool>> Contains<T>(string property, IEnumerable<dynamic> values, T item) { ParameterExpression pe = Expression.Parameter(item.GetType(), "c"); Expression columnNameProperty = Expr
private Expression<Func<T, bool>> Contains<T>(string property, IEnumerable<dynamic> values, T item)
{
ParameterExpression pe = Expression.Parameter(item.GetType(), "c");
Expression columnNameProperty = Expression.Property(pe, property);
var someValueContain = Expression.Constant(values, values.GetType());
var convertExpression = Expression.Convert(columnNameProperty, typeof(Guid));
Expression expression = Expression.Call(someValueContain, "Contains", new Type[] { }, convertExpression);
return Expression.Lambda<Func<T, bool>>(expression, pe);
}
这只不过是一种语法上的糖分,它会胜过你:) 问题是
Contains
确实不是数据查询
上的方法-它是System.Linq.Queryable
中的静态方法。C#编译器通过扩展方法为您处理此问题,但这只是C#编译器-它不是IL的功能,而是C#的功能。因此,当您操作表达式树或发出原始IL时,您必须自己处理它:
private Expression<Func<T, bool>> Contains<T, V>
(string property, IQueryable<V> values, T item)
{
ParameterExpression pe = Expression.Parameter(item.GetType(), "c");
Expression columnNameProperty = Expression.Property(pe, property);
var someValueContain = Expression.Constant(values, values.GetType());
var convertExpression = Expression.Convert(columnNameProperty, typeof(V));
Expression expression =
Expression.Call
(
(
((Expression<Func<bool>>)
(() => Queryable.Contains(default(IQueryable<V>), default(V)))
)
.Body as MethodCallExpression).Method,
someValueContain,
convertExpression
);
return Expression.Lambda<Func<T, bool>>(expression, pe);
}
(自动生成的方式与实际的Func
委托相同)
这样可以简化获取方法信息的过程:
Method((IQueryable<T> queryable, T item) => queryable.Contains(item))
Method((IQueryable可查询,T项)=>queryable.Contains(项))
或者(为了避免产生所有可能的重载):
Method(()=>default(IQueryable).Contains(default(T)))
Contains实际上是System.Linq.Queryable
上的一个扩展方法。为什么values
DataQuery
?具体类型在哪里丢失的?(()=>Queryable.Contains).Method
以前从未见过这种方法-聪明@Rob我已经开始几乎完全使用它(尽管我通常将它放在某个地方的静态只读
字段中)-不仅可以避免查找正确重载的麻烦,而且还可以安全地重命名方法等。有一点额外的编译时保护:))虽然现在我正在查看它,但实际上我在那里犯了一个错误。我得把它修好:D@Aron我修好了。我忘了我做了很多扩展方法和助手方法,使它比默认情况下更好:DAh…你能添加扩展方法吗?仍在试图找出其中一些…@Bakri对,您需要确保两个查询项来自相同的数据上下文。我想您是在检索各自新创建的上下文?
private Expression<Func<T, bool>> Contains<T, V>
(string property, IQueryable<V> values, T item)
{
ParameterExpression pe = Expression.Parameter(item.GetType(), "c");
Expression columnNameProperty = Expression.Property(pe, property);
var someValueContain = Expression.Constant(values, values.GetType());
var convertExpression = Expression.Convert(columnNameProperty, typeof(V));
Expression expression =
Expression.Call
(
(
((Expression<Func<bool>>)
(() => Queryable.Contains(default(IQueryable<V>), default(V)))
)
.Body as MethodCallExpression).Method,
someValueContain,
convertExpression
);
return Expression.Lambda<Func<T, bool>>(expression, pe);
}
public static MethodInfo Method<TR>(Expression<Func<TR>> expression)
{
return (expression.Body as MethodCallExpression).Method;
}
public static MethodInfo Method<T1, TR>(Expression<Func<T1, TR>> expression)
{
return (expression.Body as MethodCallExpression).Method;
}
Method((IQueryable<T> queryable, T item) => queryable.Contains(item))
Method(() => default(IQueryable<T>).Contains(default(T)))