我在框架4.0上。这是一个WPF应用程序,在sql server CE上,这有点限制。 我有一个看起来像这样的实体:
public class TimeEvent
{
public int Id
{get; set;}
public DateTime EventDate
{get; set;}
public bool CheckIn
{get; set;}
}
我有两种类型的事件,一种用于登记(CheckIn
为真),另一种用于结帐(CheckIn
为假)。每个事件每天发生一次。
我想用linq实体做的是最终得到一组像这样的对象:
public class Diff
{
public DateTime Date //The date of both events
{get; set;}
public DateTime CheckInTime //Time of first event
{get; set;}
public DateTime CheckOutTime //Time of second event
{get; set;}
public int Hours //Difference in hours.
{ get { return (CheckOutTime - CheckInTime).Hours;}
}
有适当的验证规则,因此每天只能在一天内发生一种类型的事件。 我尝试使用聚合函数,但我真的没有到达任何地方。 谢谢!
答案 0 :(得分:2)
按EventDate
日期部分对时间事件进行分组。为此,您需要使用EntityFunctions.TruncateTime
方法(简单EventDate.Date
将无法使用Entity Framework)。
var query = from t in db.TimeEvents
group t by EntityFunctions.TruncateTime(t.EventDate) into g
let checkIn = g.Min(x => x.EventDate)
let checkOut = g.Max(x => x.EventDate)
select new Diff {
Date = g.Key,
CheckInTime = checkIn,
CheckOutTime = checkOut
};
您还可以使用EntityFunctions.DiffHours(checkOut, checkIn)
计算服务器端的时差。
答案 1 :(得分:0)
我想您有一个TimeEvent
s(List<TimeEvent>
)列表,我会将其视为timeEvents
。
我的所有代码都在下面给出。
List<TimeEvent> timeEvents = new List<TimeEvent>();
//dummy values.
DateTime now = DateTime.Now;
for (int i = 0; i < 8; i++)
{
timeEvents.Add(new TimeEvent() { Id = i, EventDate = now, CheckIn = false });
now = now.Add(TimeSpan.Parse("3:1"));
timeEvents.Add(new TimeEvent() { Id = i, EventDate = now, CheckIn = true });
now = now + TimeSpan.Parse("1");
}
//group by
var dataSet = timeEvents.GroupBy(a => a.EventDate.Date);
List<Diff> diffs = new List<Diff>();
foreach (var x in dataSet)
{
if (!(x.Count() == 1))
{
diffs.Add(new Diff() { Date = x.ElementAt(0).EventDate.Date, CheckInTime = (x.ElementAt(0).CheckIn == true) ? x.ElementAt(0).EventDate : x.ElementAt(1).EventDate, CheckOutTime = (x.ElementAt(0).CheckIn == false) ? x.ElementAt(0).EventDate : x.ElementAt(1).EventDate });
}
}
//diffs list is full. now you can use the diffs as you like :)
答案 2 :(得分:0)
无论您创建什么聚合委托,都需要通过EF将其转换为SQL。即使您的数据非常干净且订购,这将是一个挑战。为什么不直接使用它。
static IEnumerable<Diff> GetDiffs(YourContext context)
{
bool? checkedIn;
DateTime lastDate;
foreach (var event in context.TimeEvents.OrderBy(te => te.EventDate))
{
if ((checkedIn.HasValue && checkedIn.Value = !event.CheckIn) ||
(!checkedIn.HasValue && event.CheckIn))
{
if (checkedIn.HasValue && !event.CheckIn)
{
yield return new Diff
{
CheckInTime = lastDate;
CheckOutTime = event.EventDate;
};
}
checkedIn = event.CheckIn;
lastDate = event.EventDate;
}
}
}
这样,数据的开始位置或正确执行触发器无关紧要。我也忽略了你的虚假Diff.Date
财产。它不处理签入期间的过渡日限制。