使用表达式引用类的属性,然后在LINQ查询中使用该表达式

mf98qq94  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(151)

我需要能够通过表达式引用对象的属性,我是这样做的:

Expression<Func<MyFirstModel, object>> MyFirstModelIdProperty = x => x.Id;

Intellisense允许我这样做,但我不确定这是正确的声明。
现在,我尝试在LINQ表达式中实际使用属性引用

int id = 500;
myFirstModelDataSet.SingleOrDefault(x=> MyFirstModelIdProperty == id); //??

显然,这甚至不是编译,但我不知道如何去。
最终我也得支持这个案子

Expression<Func<MyFirstModel, object>> MyFirstModelIdProperty = x => x.Id;
Expression<Func<MySecondModel, object>> MySecondModelIdProperty = x => x.TheId;

MySecondModel secondModel = new MySecondModel() { TheId = 55 };
myFirstModelDataSet.SingleOrDefault(x=> MyFirstModelIdProperty == MySecondModelIdProperty); //??

这里的最终目标是,我希望人们能够告知我的项目如何通过“id”查询DbSet,而不必直接指定属性(通过字符串)。
有什么想法吗

7kqas0il

7kqas0il1#

假设你正在使用IQueryable(否则只是编译表达式)-最简单的选择是使用LINQKit

myFirstModelDataSet.AsExpandable().SingleOrDefault(x=> MyFirstModelIdProperty.Invoke(x) == (object)id);

否则,您将需要自己执行一些表达式树编译:

int someId = 42;
var equalExp = Expression.Equal(MyFirstModelIdProperty.Body, Expression.Convert(Expression.Constant(someId), typeof(object)));
var expression = Expression.Lambda<Func<Person, bool>>(equalExp, MyFirstModelIdProperty.Parameters);
myFirstModelDataSet.SingleOrDefault(expression);

对于第二个,你需要执行参数替换,这可以很容易地用ReplacingExpressionVisitor完成。大致如下:

var secondOp = new ReplacingExpressionVisitor(MySecondModelIdProperty .Parameters, MyFirstModelIdProperty.Parameters)
        .Visit(MySecondModelIdProperty.Body);

var equalExp = Expression.Equal(MyFirstModelIdProperty.Body, secondOp);

相关问题