C# 如何获取c中员工的总假期数#

C# 如何获取c中员工的总假期数#,c#,asp.net,sql-server,C#,Asp.net,Sql Server,我的SQL查询返回了一些记录集,从中可以得到员工姓名以及他当月的开始和结束休假日期。我的问题是,我得到了同一名员工的两份记录,但休假日期不同。现在,我需要该员工休假时的所有日期(应结合他的两个假期数据) 我的SQL查询是: SELECT distinct emp.emp_name, NULL as start_date, NULL as end_date FROM employee_details emp WHERE emp.group_name = 'A' a

我的SQL查询返回了一些记录集,从中可以得到员工姓名以及他当月的开始和结束休假日期。我的问题是,我得到了同一名员工的两份记录,但休假日期不同。现在,我需要该员工休假时的所有日期(应结合他的两个假期数据)

我的SQL查询是:

SELECT distinct emp.emp_name, 
       NULL as start_date,
       NULL as end_date 
FROM employee_details emp 
WHERE emp.group_name = 'A' and 
      Emp_Id not in (SELECT distinct emp.Emp_Id 
                     FROM employee_details emp, offshore_leave_calendar olc 
                     WHERE emp.emp_id = olc.emp_id AND 
                           emp.group_name = 'A' and 
                           datepart(mm,olc.start_date) = datepart(mm, getdate()))
union 

SELECT distinct emp.emp_name,
       olc.Start_Date,
       olc.End_Date 
FROM employee_details emp, offshore_leave_calendar olc     
WHERE emp.emp_id = olc.emp_id AND 
      emp.group_name = 'A' and 
      datepart(mm, olc.start_date) = datepart(mm,getdate())
我对上述查询的输出是:

Emp_Name            start_date               end_date
John         
Sophia       
Olivia
Davis          3/20/2017 12:00:00 AM    3/24/2017 12:00:00 AM
Clark          3/21/2017 12:00:00 AM    3/24/2017 12:00:00 AM
Paul         
Thomas         3/21/2016 12:00:00 AM    3/29/2016 12:00:00 AM
Thomas         3/6/2017 12:00:00 AM     3/10/2017 12:00:00 AM
在上述输出中,Thomas本月休假两次。所以我想把托马斯休假时的所有日期都列在C#的列表中。输出日期应为:

3/06/2016
3/07/2016
3/08/2016
3/09/2016
3/10/2016
3/21/2016
3/22/2016
3/23/2016
3/24/2016
3/25/2016
3/26/2016
3/27/2016
3/28/2016
3/29/2016
有人能帮我吗

我的名单如下:

 List<LeaveData> leaveList = new List<LeaveData>();
每月的每个日期,我都要指派一名员工,不应指派正在休假的员工。因此,我循环了一个月的所有日期,并编写了以下代码来查找员工休假的日期:

for (int i = 0; i < dates.Length; i++)
{
    for (DateTime? date = leaveList[index].start_date; date <= leaveList[index].end_date; date = date.Value.AddDays(1))
            {
                allDates.Add(date);
            }
}
for(int i=0;i对于(DateTime?date=leaveList[index]),start\u date;date具有以下属性的类

public class EmployeeLeave
{
   public string empName {get; set;}
   public List<DateTime> LeavesDate {get;set;}
}
公共类员工休假
{
公共字符串empName{get;set;}
公共列表LeavesDate{get;set;}
}
迭代所有员工

var allEmployeeLeaveList = new List<EmployeeLeave>();

  foreach(var employee in LeaveData)
  {
    var tempDate = employee.StartDate.valueOrDefault();
    while((employee.EndDate.valueOrDefault() - tempDate).TotalDays > 0)
        {
         if( allEmployeeLeaveList .Any(x=>x.empName == employee.Emp_Name ))
           {
              allEmployeeLeaveList .Where(x=>x.empName == employee.Emp_Name    ).LeavesDate .Add(tempDate);
           }
       else
           {
        allEmployeeLeaveList.Add(new EmployeeLeave
                                     {
                                      empName  = employee.Emp_Name ,
                                      LeavesDate = new List<DateTime>  
                                                     {tempDate}         
                                      });
           }

        tempDate.AddDays(1)
        }
  }
var allEmployeeLeaveList=new List();
foreach(LeaveData中的var员工)
{
var tempDate=employee.StartDate.valuerDefault();
而((employee.EndDate.valueOrDefault()-tempDate).TotalDays>0)
{
if(allEmployeeLeaveList.Any(x=>x.empName==employee.Emp_Name))
{
allEmployeeLeaveList.Where(x=>x.empName==employee.Emp_Name).LeavesDate.Add(tempDate);
}
其他的
{
allEmployeeLeaveList.Add(新员工休假)
{
empName=employee.Emp_Name,
LeavesDate=新列表
{tempDate}
});
}
tempDate.AddDays(1)
}
}

假设您有一份C语言的员工名单#

剩下的只是
的简单linq,其中
SelectMany
是将结果投影并展平到相同的序列中

编辑
作为您的评论:如果您的数据在
leaveList[index]
中,那么您只需将“Thomas”替换为
leaveList[index].Emp_Name
。此外,我还添加了空日期检查:

IEnumerable<DateTime> leaveDates = 
        employees.Where(emp=>emp.Emp_Name == leaveList[index].Emp_Name && 
                             emp.StartDate.HasValue && emp.EndDate.HasValue)
                 .SelectMany(emp =>
                     Enumerable.Range(0,
                                emp.EndDate.Value.Subtract(emp.StartDate.Value).Days + 1)
                              .Select(d => e.StartDate.Value.AddDays(d)));
IEnumerable leaveDates=
employees.Where(emp=>emp.emp_Name==leaveList[index]。emp_Name&&
emp.StartDate.HasValue&&emp.EndDate.HasValue)
.SelectMany(emp=>
可枚举范围(0,
emp.EndDate.Value.Subtract(emp.StartDate.Value).Days+1)
.选择(d=>e.StartDate.Value.AddDays(d));

请参阅您希望将休假日期分配给“当前员工”的要求,我觉得这很容易,而且只要我们首先有完整的信息,就可以用sql本身完成

分配员工的标准是什么。 我对你的输出进行了研究,假设它是另一个CTE

declare @t table(Emp_Name varchar(50),start_date datetime,end_date datetime)
insert into @t VALUES
('John',null,null)
,('Sophia',null,null)
,('Olivia',null,null)
,('Davis','3/20/2017 12:00:00 AM ',   '3/24/2017 12:00:00 AM')
,('Clark','3/21/2017 12:00:00 AM','3/24/2017 12:00:00 AM')
,('Paul',null,null)
,('Thomas','3/21/2016 12:00:00 AM',    '3/29/2016 12:00:00 AM')
,('Thomas','3/6/2017 12:00:00 AM',     '3/10/2017 12:00:00 AM')
;With CTE as
(
select  *,ROW_NUMBER()over(partition by Emp_Name order by start_date)RN 
,DATEDIFF(day,start_date,end_date) rn1
from @t
where start_date is not null

)
,CTE1 AS(

select Emp_Name,start_date , end_date,rn,rn1 from cte

UNION ALL
SELECT c.Emp_Name,DATEADD(day,1,c1.start_date), c.end_date,c1.rn
,c1.rn1
FROM cte c
inner join cte1 c1 on c.Emp_Name=c1.Emp_Name
where c.rn=c1.rn
and  C1.start_date<c.end_date
)

SELECT Emp_Name
,start_date leavedates 
FROM CTE1
order by Emp_Name
declare@t表(Emp\u Name varchar(50)、开始日期日期时间、结束日期日期时间)
插入到@t值中
('John',null,null)
,('Sophia',空,空)
,('Olivia',空,空)
,(《戴维斯》,《2017年3月20日12:00:00 AM》,《2017年3月24日12:00:00 AM》)
,(《克拉克》,《2017年3月21日12:00:00 AM》,《2017年3月24日12:00:00 AM》)
,('Paul',空,空)
,(《托马斯》,《2016年3月21日12:00:00 AM》,《2016年3月29日12:00:00 AM》)
,(《托马斯》,《2017年3月6日12:00:00 AM》,《2017年3月10日12:00:00 AM》)
;以CTE为例
(
选择*,行号()覆盖(按Emp名称顺序按开始日期划分)RN
,DATEDIFF(天,开始日期,结束日期)rn1
来自@t
其中开始日期不为空
)
,CTE1 AS(
从cte中选择Emp名称、开始日期、结束日期、rn、rn1
联合所有
选择c.Emp\U名称、日期添加(日期1、c1.开始日期)、c.end\U日期、c1.rn
,c1.rn1
来自cte c
c.Emp_Name=c1.Emp_Name上的内部连接cte1 c1
其中c.rn=c1.rn

和C1.开始日期请共享您的C代码。按员工姓名对数据集中的记录进行分组您是如何做到的?实体框架还是什么?@KobyDouek我已经编辑了我的问题。此员工列表将是包含我的emp名称、开始日期、结束日期的列表?以及someList.listDateTime.Add行中的listDateTime是什么(tempDate);但这里我希望列表只针对离开列表[index]指向的员工进行迭代,例如这里的离开列表[index]指向Thomas,因此它应该只迭代Thomas的休假,即从6-10到21-29。查看答案,它将返回与您期望的结果相同的结果,但无论如何,上面的代码片段将绑定所有员工的所有休假日期。此外,您可以根据您的需要在e.Emp_Name上筛选任何特定员工。它给出的错误可能会未将类型字符串转换为bool。缺少第二个变量
=
。请立即检查。它现在在e上出现错误:错误在此作用域中无法声明名为“e”的局部或参数,因为该名称在封闭的局部作用域中用于定义局部或参数。显然,当前作用域中有另一个名为e的变量。我已更改为emp、 …请随意更改。我已经根据我的更改了代码:IEnumerable leaveDates=leaveList.Where(item2=>item2.Emp_Name==leaveList[index].Emp_Name)。SelectMany(item2=>Enumerable.Range(0,item2.leaveList[index]。end_date.Subtract(item2.leaveList[index]。start_date+1)。选择(d=>tem2.leaveList[index].start_date.AddDays(d))),但这也给出了错误:CS1061“LeaveData”不包含“leaveList”的定义,并且找不到接受“LeaveData”类型的第一个参数的扩展方法“leaveList”(是否缺少using指令或程序集引用?)
Enumerable.Range(0, e.EndDate.Subtract(e.StartDate).Days + 1)
                          .Select(d => e.StartDate.AddDays(d)));
IEnumerable<DateTime> leaveDates = 
        employees.Where(emp=>emp.Emp_Name == leaveList[index].Emp_Name && 
                             emp.StartDate.HasValue && emp.EndDate.HasValue)
                 .SelectMany(emp =>
                     Enumerable.Range(0,
                                emp.EndDate.Value.Subtract(emp.StartDate.Value).Days + 1)
                              .Select(d => e.StartDate.Value.AddDays(d)));
declare @t table(Emp_Name varchar(50),start_date datetime,end_date datetime)
insert into @t VALUES
('John',null,null)
,('Sophia',null,null)
,('Olivia',null,null)
,('Davis','3/20/2017 12:00:00 AM ',   '3/24/2017 12:00:00 AM')
,('Clark','3/21/2017 12:00:00 AM','3/24/2017 12:00:00 AM')
,('Paul',null,null)
,('Thomas','3/21/2016 12:00:00 AM',    '3/29/2016 12:00:00 AM')
,('Thomas','3/6/2017 12:00:00 AM',     '3/10/2017 12:00:00 AM')
;With CTE as
(
select  *,ROW_NUMBER()over(partition by Emp_Name order by start_date)RN 
,DATEDIFF(day,start_date,end_date) rn1
from @t
where start_date is not null

)
,CTE1 AS(

select Emp_Name,start_date , end_date,rn,rn1 from cte

UNION ALL
SELECT c.Emp_Name,DATEADD(day,1,c1.start_date), c.end_date,c1.rn
,c1.rn1
FROM cte c
inner join cte1 c1 on c.Emp_Name=c1.Emp_Name
where c.rn=c1.rn
and  C1.start_date<c.end_date
)

SELECT Emp_Name
,start_date leavedates 
FROM CTE1
order by Emp_Name