[英]Use an Expression<Func> within an Expression<Func>
The below code works fine (throws no translation error):下面的代码工作正常(不引发翻译错误):
string text = "someString";
string refId = "refId";
bool forward = true;
IQueryable<Tin> q = queryable.Where(o => forward ? text.IsGreaterThan(refId) : text.IsLessThan(refId));
var x = await q.ToArrayAsync();
IsGreaterThan()
and IsLessThan()
are methods that have been registered in OnModelCreating(ModelBuilder builder)
from dbContext, as explained in this answer . IsGreaterThan()
和IsLessThan()
是已在 dbContext 的OnModelCreating(ModelBuilder builder)
中注册的方法,如本答案中所述。 So the problem is not with those methods.所以问题不在于这些方法。
The below code doesn't work:下面的代码不起作用:
string refId = "refId";
Expression<Func<Tin, string>> key = obj => obj.Id;
bool forward = true;
IQueryable<Tin> q = queryable.Where(o => forward ? key.Compile()(o).IsGreaterThan(refId) : key.Compile()(o).IsLessThan(refId));
var x = await q.ToArrayAsync();
It throws the below error.它引发以下错误。
System.InvalidOperationException: The LINQ expression 'DbSet<Follow>
.Where(f => f.FollowerId == __userId_0)
.Where(f => Invoke(__Compile_1, f[Follow])
.IsGreaterThan(__refId_2))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().
I understand why it fails.我明白为什么会失败。 Expression<Func<>>.Compile()
returns a Func<>
and those cannot be used in Linq to Sql. Expression<Func<>>.Compile()
返回一个Func<>
并且不能在 Linq 到 Sql 中使用。 So I've been looking for workarounds.所以我一直在寻找解决方法。
The most promising I found is from this answer .我发现的最有希望来自这个答案。 It worked as expected in the fiddle he provided, but for some reason, it didn't work for me.它在他提供的小提琴中按预期工作,但由于某种原因,它对我不起作用。 My code after implementing his answer:实现他的答案后我的代码:
string refId = "refId";
Expression<Func<Tin, string>> key = obj => obj.Id;
bool forward = true;
Func<Tin, string> keyFunc = key.Compile();
Expression<Func<Tin, bool>> where = o => forward ? keyFunc(o).IsGreaterThan(refId) : keyFunc(o).IsLessThan(refId);
where.Replace(() => keyFunc, key);
IQueryable<Tin> q = queryable.Where(where);
var x = await q.ToArrayAsync();
Is there some other way to nest Expression<Func<>>
s?还有其他方法可以嵌套Expression<Func<>>
s吗?
EDIT : As mentioned by @pinkfloydx33:编辑:正如@pinkfloydx33 所述:
where.Replace(() => keyFunc, key);
should have been:本来应该:
where = where.Replace(() => keyFunc, key);
Funny enough, I make this same mistake with string.Replace()
a loooot.有趣的是,我在string.Replace()
中犯了同样的错误。 It works fine now after this.在此之后它现在工作正常。
This feature is not supported by EF, and i don't know why;) You have to install LINQKit and use AsExpandable()
adn Invoke
instead of Compile
: EF 不支持此功能,我不知道为什么;)您必须安装 LINQKit 并使用AsExpandable()
和Invoke
而不是Compile
:
string refId = "refId";
Expression<Func<Tin, string>> key = obj => obj.Id;
bool forward = true;
IQueryable<Tin> q = queryable
.AsExpandable()
.Where(o => forward ? key.Invoke(o).IsGreaterThan(refId) : key.Invoke(o).IsLessThan(refId));
var x = await q.ToArrayAsync();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.