我有这个代码,已成功转换为 SQL:
public class MachineUtils
{
public static Expression<Func<Machine, bool>> IsDaily()
{
return model => (model.Distribution == EmailType.Daily) ||
model.IncludeMail;
}
}
var query = _dbContext.Machines.AsNoTracking().Where(MachineUtils.IsDaily());
但是我需要提取检查逻辑来单独的函数,以避免应用程序中的代码重复。
所以我需要类似的东西,因为我想在应用程序的其他地方调用
CheckIsDaily
函数:
public class MachineUtils
{
public static bool CheckIsDaily(IMachine model)
{
return (model.Distribution == EmailType.Daily) ||
model.IncludeMail;
}
public static Expression<Func<Machine, bool>> IsDaily()
{
return model => CheckIsDaily(model);
}
}
但是在这种情况下,我收到错误:
无法翻译 LINQ 表达式 'DbSet().Where(m => MachineUtils.CheckIsDaily(m))'
如何实现?
您遇到该错误的原因是实体框架无法将 CheckIsDaily 方法调用转换为 SQL,因为它是自定义方法而不是内置 SQL 函数。为了实现避免代码重复的目标,同时仍然能够使用 LINQ 查询中的逻辑,您可以结合使用表达式树和自定义可重用谓词。
public static class MachineUtils
{
public static Expression<Func<IMachine, bool>> CheckIsDailyPredicate = model =>
(model.Distribution == EmailType.Daily) ||
model.IncludeMail;
public static Expression<Func<IMachine, bool>> IsDaily()
{
return CheckIsDailyPredicate;
}
}
var query = _dbContext.Machines.AsNoTracking().Where(MachineUtils.CheckIsDailyPredicate);
这样,您就将逻辑定义为可重用的表达式树,实体框架可以将其转换为 SQL,因为它使用表达式。