转换?:语句来处理2个以上的答案

时间:2012-08-31 19:30:20

标签: c# linq

我对编程很新,但我的任务是维护一些前任员工创建的应用程序。我有一个?:语句现在需要处理的不仅仅是一个真或假的语句,但我不知道如何去做。有问题的代码是:

    MailDomainContext mail = new MailDomainContext();
      mail.Load(mail.GetMailsQuery("Workforce Attendence Issue",
               loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First().Username,
               (loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First().EmployeeShiftID >= 2 ? "supervisor1" : "supervisor2"),
               loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First().FirstName,
               attendence.AttendenceDate.ToString("MM/dd/yyyy"),
               attendence.TimeLost,
               loadAbs.Entities.Where(abs => abs.AbsenceID == attendence.AbsenceID).First().AbsenceDescription,
               (from inf in loadAtt.Entities
               where inf.EmployeeID == _EmployeeID
               where inf.AttendenceDate > DateTime.Now.AddDays(30 * -1)
               where inf.Approved == false
               select inf).Count() + 1,
               attendence.UTOUsed
               ), null, null);

更具体地说,这一行:

    (loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First().EmployeeShiftID >= 2 ? "supervisor1" : "supervisor2"),

我需要在列表中再添加4个主管,但还没有找到一种方法来做到这一点,而不会让其他所有人感到不快。如果这个问题太简单,或者我遗漏了一些你可能需要知道的细节,我很抱歉,因为我说我对这一切都很陌生。

5 个答案:

答案 0 :(得分:4)

这段代码不必要地难以维护,而且效率低,而且防御性也不高。代码正在检索员工三次。

loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First().Username

如果_EmployeeID的员工不存在,上述行(和其他人)将抛出异常。相反,您可以使用FirstOrDefaultSingleOrDefault,如果您希望只有一名员工拥有该ID(应该是这种情况,因为它看起来像该实体的主键)。如果loadEmp实际上是实体框架DbContext,那么您也可以使用Find

您可以执行此查询一次,并将结果存储在本地变量中。

var employee = loadEmp.Entities.SingleOrDefault(emp => emp.EmployeeID == _EmployeeID);

if (employee == null)
{
   // Handle employee not found
}

然后根据员工获取管理员字符串,您可以创建一个方法,该方法获取计算管理员字符串所需的最少量信息,并将其传递给方法以获得结果。

GetSupervisorRole(employee.EmployeeShiftID);

...

private string GetSupervisorRole(int employeeShiftID)
{
   // Logic here
}

答案 1 :(得分:3)

一种方法是将该代码提取到方法中,并以您想要的任何方式编写该方法。

另一种方法是使用字典将键(如果你的数量很少)映射到值。

var id =3;
var mapping = new Dictionary<int, string>() { 
  { 1, "first" },
  { 2, "second" },
  { 3, "first" } //you can map 2 values (1,3) to the same "first" string
};

string value;
if (!mapping.TryGetValue(id, out value))
{
  value = "unknown";
}

答案 2 :(得分:2)

创建以下方法:

string GetSupervisor(int employeeShiftId) {
    if (employeeShiftId == 1) supervisor = "supervisor1";
    else if (employeeShiftId == 2) supervisor = "supervisor2";
    else if (employeeShiftId == 3) supervisor = "supervisor3";
    else if (employeeShiftId == 4) supervisor = "supervisor4";
}

然后从您的代码中调用它并将结果分配给变量supervisor,然后您可以在mail.Load()中使用该变量:

int employeeShiftId = loadEmp.Entities
          .Where(emp => emp.EmployeeID == _EmployeeID).First()
          .EmployeeShiftID;
string supervisor = GetSupervisor(employeeShiftId);

MailDomainContext mail = new MailDomainContext();
mail.Load(mail.GetMailsQuery("Workforce Attendence Issue",
               loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First().Username,
               supervisor, // <-- Then use it here
               ...
);

答案 3 :(得分:2)

我会替换整个部分

loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First().Username,
(loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First().EmployeeShiftID >= 2 ? "supervisor1" : "supervisor2"),
 loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First().FirstName,

//Assign these variables ahead of time so others reading your code can 
//figure out what's going on
var EmpID = loadEmp.Entities.Where(emp => emp.EmployeeID == _EmployeeID).First();
var UserName = EmpID.UserName;
var FirstName = EmpID.FirstName;
var Title = GetTitle(EmpID.EmployeeShiftID);

//Your original call
Mail.Load(mail.GetMailsQuery("Workforce Attendence Issue",
     UserName,
     Title,
     FirstName,
     //...Etc
);

//New method you will need to add, you could do this logic in line, but this will
//be less messy
private string GetTitle(int ShiftID)
{
    switch (ShiftID)
    {
         case 1:
             return "supervisor1";
             break;
         case 2:
             return "supervisor2";
             break;
         //...etc
    }
}

答案 4 :(得分:1)

这不是一个好主意,但你可以将内联结合起来,如果是这样的话:

    static void Main(string[] args)
    {
        int EmpId = 2;
        string supervisor = EmpId == 4 ? "Supervisor4" :
                            EmpId == 3 ? "Supervisor3" :
                            EmpId == 2 ? "supervisor2" :
                                         "supervisor1" ;
        Console.WriteLine(supervisor);

    }

您可以在另一个堆栈问题中看到另一个示例:Legible or not: C# multiple ternary operators + Throw if unmatched

我可能会选择像KDiTraglia那样的方法,你只需要传入EmpId并获取主管名称,或者像Alexei Levenkov那样提出字典查找方法。