LINQ where子句中的可变条件

时间:2014-09-23 12:38:43

标签: c# .net linq

我有一个我没有创建的数据库,我无法修改。我需要运行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却没有。我觉得这应该很容易,但我很难过。

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

5 个答案:

答案 0 :(得分:7)

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

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

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

答案 1 :(得分:2)

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

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;

如果column的值可以为null:

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

答案 2 :(得分:1)

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

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

...等

答案 3 :(得分:1)

您可以构建表达式树来表示您想要手动执行的条件,而不是像您尝试的那样使用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);

答案 4 :(得分:0)

  • 一个选项

    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;
            ...
    }