简体   繁体   English

扩展 LINQ 表达式

[英]Extending LINQ Expressions

Newbie LINQ Expressions question-新手 LINQ 表达式问题-

Expression<Func<TLookupModel, TValue>> idSelector;
IEnumerable<TLookupModel> source;
TValue id;

I'm trying to do (pseudo-code):我正在尝试做(伪代码):

source.AsQueryable().FirstOrDefault(x => idSelector == id)

My feeble attempt thus far is along the lines of:到目前为止,我的微弱尝试是:

var expressionParam = idSelector.Parameters.First();

ConstantExpression selectedValueConstant = Expression.Constant(id, typeof(TValue));

var idEqualExpression = Expression.Equal(idSelector, selectedValueConstant);

var lambda = Expression.Lambda<Func<TLookupModel, bool>>(idEqualExpression, expressionParam);

var selectedSourceItem = source.AsQueryable().FirstOrDefault(lambda);

I think that gives you a guess as to how I've been thinking so far.我想这可以让你猜测我到目前为止的想法。 I've tried with and without the parameters, different combinations of Expression method calls, trying to get the "parameter" to come from the FirstOrDefault() call, but after reading lots of tutorials I can't get my head around how to extend a "member" expression to equal a constant in this way.我尝试过使用和不使用参数,不同的 Expression 方法调用组合,试图从FirstOrDefault()调用中获取“参数”,但是在阅读了大量教程后,我无法理解如何扩展一个“成员”表达式以这种方式等于一个常量。

You got really close.你真的很接近。

Your idExpression is an Expression in the form of x => x.Property .您的 idExpression 是x => x.Property形式的x => x.Property However, you're passing the whole expression to the Equal expression.但是,您将整个表达式传递给 Equal 表达式。 Change that to pass only the body:将其更改为仅传递正文:

var idEqualExpression = Expression.Equal(idSelector.Body, selectedValueConstant);

Then you can compile the lambda and pass it to FirstOrDefault without casting to a queryable:然后您可以编译 lambda 并将其传递给 FirstOrDefault 而不转换为可查询的:

var selectedSourceItem = source.FirstOrDefault(lambda.Compile());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM