C# 如何获取c中员工的总假期数#
我的SQL查询返回了一些记录集,从中可以得到员工姓名以及他当月的开始和结束休假日期。我的问题是,我得到了同一名员工的两份记录,但休假日期不同。现在,我需要该员工休假时的所有日期(应结合他的两个假期数据) 我的SQL查询是: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
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