C# lambda表达式内泛型类型的访问属性
标题可能模棱两可,但让我解释一下 我正在使用MongoDb和MongoDb的c#驱动程序,我们可以创建一个C# lambda表达式内泛型类型的访问属性,c#,mongodb,generics,lambda,C#,Mongodb,Generics,Lambda,标题可能模棱两可,但让我解释一下 我正在使用MongoDb和MongoDb的c#驱动程序,我们可以创建一个FilterDefinition来创建一个过滤器来获取数据,如下所示: var Filter = Builders<TestClass>.Filter.Eq(x => x.AnyProperty, Value); var Filter = Builders<T>.FIlter.Eq(x => x.AnyProperty, value); public
FilterDefinition
来创建一个过滤器来获取数据,如下所示:
var Filter = Builders<TestClass>.Filter.Eq(x => x.AnyProperty, Value);
var Filter = Builders<T>.FIlter.Eq(x => x.AnyProperty, value);
public FilterDefinition<TDocument> Eq<TField>(FieldDefinition<TDocument, TField> field, TField value);
但它不会从数据库返回结果,因为这样做:
var Filter = Builders<MyClass>.FIlter.Eq("PropertName", value);
代码中的
FIlter.Eq(x=>x.GetType().GetProperty(PropertyName),value)
,我的理解是Mongo驱动程序需要一个表达式
,当您使用元数据(如原始情况下的x=>x.AnyProperty
在这种情况下,您需要显式地提供MemberExpression
,如下所示
现在,您可以向过滤器.Eq
值memberAccessExpression
,在这种情况下,如果AnyProperty
不是类型T
的一部分,它将在运行时失败,因为它在运行时经过验证
在ExpressionTrees
中,这是对x=>x.AnyProperty
编辑1:
查看Mongo DB驱动程序文档,以下是有关的重要详细信息,示例如下:
var builder = Builders<Widget>.Filter;
var filter = builder.Eq(widget => widget.X, 10) & builder.Lt(widget => widget.Y, 20);
在这种情况下,我们需要一个泛型类型t文档
,它是主类和t字段
,它是应用过滤器的字段类型,因此在您的情况下,代码应该是:
var builder = Builders<T>.Filter;
// Use makeMemberAccessExpression created above
var filter = builder.Eq(Expression.Lambda<Func<T,string>>(makeMemberAccessExpression), "<stringValue>");
var builder=Builders.Filter;
//使用上面创建的makeMemberAccessExpression
var filter=builder.Eq(Expression.Lambda(makeMemberAccessExpression));
要点:
TDocument
和TField
,在这里您只使用一种,因此对于上面的代码,它将被限制为字符串作为TField
的类型,直到并且除非您将其设置为通用类型,这是您的选择,否则,所有字段都应为您提供的特定类型,在本例中为字符串TField
,否则它将不起作用,并在编译时失败Eq(FieldDefinition,TField)
,它将以类似的方式工作,但由于它需要FieldDefinition
,我们需要提供表达式作为类的一部分,这两个重载都转换为类似的代码
这个错误来自哪里?是Mongo驱动程序还是你的代码,因为如果它是你的代码,那么它可能会修复,而且更复杂的是Mongo驱动程序导致了它还有
过滤器的定义。Eq
,它需要什么类型的对象,我想,它是一种对象类型,我假设这不起作用,因为驱动程序试图将其转换为C#以外的查询。使用GetType
当然不起作用。EntityFramework也是如此。如果查询中有.net逻辑,则无法将其转换为SQL(或其他任何形式),因此会出现错误。这只是一个假设,但对我来说是有意义的。而x=>x.Bla
之所以有效,是因为x代表一个表,Bla代表一个列,因此它可以轻松地将其转换为用于查询的任何内容。请尝试x=>x.GetType().GetProperty(PropertyName).GetValue(x)
,因为它需要的是用于比较的值,而不仅仅是我头顶上的PropertyInfo
,Mongo驱动程序使用反射从MemberExpression获取属性名称x=>x.GetType().GetProperty(PropertyName)
不是MemberExpression,因此无法使用。你想解决什么问题?Eq
接受一个filterdefinition
作为第一个参数,因此我无法传递memberAccessExpression
。如果你能在问题更新中粘贴架构,我猜它需要MemberExpression
,事实上,您在实际代码中提供的Lambda是FilterDefinition
您的自定义类现在您需要发布FieldDefinition
的定义,请将其减少到有.Net代码的位置,而不是他们的自定义代码我需要找到另一种方法。。。。挖得太深会使事情变得更复杂。
var builder = Builders<Widget>.Filter;
var filter = builder.Eq(widget => widget.X, 10) & builder.Lt(widget => widget.Y, 20);
public FilterDefinition<TDocument> Eq<TField>(Expression<Func<TDocument, TField>> field,TField value)
var builder = Builders<T>.Filter;
// Use makeMemberAccessExpression created above
var filter = builder.Eq(Expression.Lambda<Func<T,string>>(makeMemberAccessExpression), "<stringValue>");