【发布时间】:2020-03-23 05:38:20
【问题描述】:
在最近发布的 Entity Framework Core 3.0 中,默认为LINQ queries are no longer evaluated on the client。我是这种变化的忠实拥护者,因为它揭示了我的项目中一些潜在危险的客户端评估,我认为这些评估已被转换为 SQL;但是,它也使我用来避免疯狂的三元链的一些辅助方法无法使用。
是否有人设法嵌套 LINQ 表达式以用于 Entity Framework Core 3.0?这是我希望实现的一个示例:
[Fact]
public async Task Can_use_custom_expression()
{
var dbContext = new ApplicationDbContext(new DbContextOptionsBuilder<ApplicationDbContext>().UseInMemoryDatabase("Test").Options);
dbContext.Users.Add(new ApplicationUser { FirstName = "Foo", LastName = "Bar" });
dbContext.SaveChanges();
string query = "Foo";
Expression<Func<string, string, bool>> valueCheck = (value, expected) => !string.IsNullOrEmpty(value) && value.Contains(expected);
var valueCheckFunc = valueCheck.Compile();
Expression<Func<ApplicationUser, bool>> whereExpression = (u) => valueCheckFunc(u.FirstName, query);
var user = await dbContext.Users
.Where(whereExpression)
.FirstOrDefaultAsync();
Assert.NotNull(user);
}
当我运行这个例子时,我得到了以下异常:
Message:
System.InvalidOperationException : The LINQ expression 'Where<ApplicationUser>(
source: DbSet<ApplicationUser>,
predicate: (a) => Invoke(__valueCheckFunc_0, a.FirstName, __query_1)
)' 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(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
就像我说的,我不想在客户端评估这个表达式,但我想避免在一个表达式中链接十几个 !string.IsNullOrEmpty(x) && x.Contains(y)。我想要一些关于如何实现这一目标的提示。
【问题讨论】:
标签: c# linq entity-framework-core entity-framework-core-3.0