LINQ where子句中的变量条件

本文关键字:变量 条件 where 子句 LINQ | 更新日期: 2023-09-27 18:24:14

我有一个数据库,我没有创建,也无法修改。我需要运行linq查询,但需要在where子句中传递一个变量。

表中列:AdvMonAM(全位)、AdvMonAMAdvTueAMAdvTuePMAdvWedAM

var column = "Adv" + dayOfWeek + time;
var employeesOnCall = from r in db.AdvOnCalls
                      where (variable column needed here) == true
                      select r.ChartEmployee;

如果我硬编码r.AdvTueAM,它可以很好地工作,但r.column == truecolumn == true不能。我觉得这应该很容易,但我被难住了。

我正在努力寻找在一天中某个特定时间待命的员工。

LINQ where子句中的变量条件

糟糕的数据库设计导致了糟糕的解决方案:

where ( (column == "AdvMonAM" && AdvMonAM == 1)
        || (column == "AdvMonPM" && AdvMonPM == 1)
      )

依此类推,对每个字段添加一个条件。(我不确定返回的数据类型。如果是bool,请删除== 1

如果数据库中的列不能为空:

string column = "Adv" + dayOfWeek + time;
var employeesOnCall = from r in db.AdvOnCalls
                      where (bool)r[column]
                      select r.ChartEmployee;

或:

string column = "Adv" + dayOfWeek + time;
var employeesOnCall = from r in db.AdvOnCalls
                      where r.Field<bool>(column)
                      select r.ChartEmployee;

如果列的值可以为空:

string column = "Adv" + dayOfWeek + time;
var employeesOnCall = from r in db.AdvOnCalls
                      where r.Field<bool?>(column)==true
                      select r.ChartEmployee;

您可以手动构建表达式树来表示您想要的条件,而不是像您尝试的那样使用lambda:

public static IQueryable<T> WhereEquals<T>(
    this IQueryable<T> query,
    string property,
    object valueToCompare)
{
    var param = Expression.Parameter(typeof(T));
    var body = Expression.Equal(
        Expression.Property(param, property),
        Expression.Constant(valueToCompare));
    var lambda = Expression.Lambda<Func<T, bool>>(body, param);
    return query.Where(lambda);
}

这允许你写:

var employeesOnCall = db.AdvOnCalls.WhereEquals(column, true)
    .Select(adv => adv.ChartEmployee);

您可以使用动态LINQ来执行以下操作:

var column = "Adv" + dayOfWeek + time;
var employeesOnCall = db.AdvOnCalls
    .Where (column + " = 1")
    .Select(x => x.ChartEmployee);

等等

  • 一种选择

    var column = "Adv" + dayOfWeek + time;
    var employeesOnCall = from r in db.AdvOnCalls
                          where GetPropByName(r, column)
                          select r.ChartEmployee;
    

    使用此功能:

    bool GetPropByName(AdvOnCall item, string column)
    {
       return (bool)item.GetType().GetProperty(column).GetValue(item, null);
    }
    
  • 更好的选择:):

    var employeesOnCall = from r in db.AdvOnCalls
                          where columnSwitch(r, dayOfWeek, time) 
                          select r.ChartEmployee;
    

    使用此功能:

    bool columnSwitch(AdvOnCall item, string dayOfWeek, string time)
    {
        if (time == "AM")
            if (dayOfWeek == "Mon")
                return item.AdvMonAM;
            else if (dayOfWeek == "Tue")
                return item.AdvTueAM;
            ...
         else // (time == "PM")
            if (dayOfWeek == "Mon")
                return item.AdvMonPM;
            else if (dayOfWeek == "Tue")
                return item.AdvTuePM;
            ...
    }