C# linq查询中的聚合对
我使用的是框架4.0。这是一个WPF应用程序,位于SQLServerCE上,有点限制。 我有一个实体,看起来像这样:C# linq查询中的聚合对,c#,linq,linq-to-entities,C#,Linq,Linq To Entities,我使用的是框架4.0。这是一个WPF应用程序,位于SQLServerCE上,有点限制。 我有一个实体,看起来像这样: public class TimeEvent { public int Id {get; set;} public DateTime EventDate {get; set;} public bool CheckIn {get; set;} } public class
public class TimeEvent
{
public int Id
{get; set;}
public DateTime EventDate
{get; set;}
public bool CheckIn
{get; set;}
}
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;}
}
我有两种类型的事件,一种用于签入(checkin
为true),另一种用于签出(checkin
为false)。每个事件每天发生一次。
我想使用linq to entities来完成的是最终得到一组对象,如下所示:
public class TimeEvent
{
public int Id
{get; set;}
public DateTime EventDate
{get; set;}
public bool CheckIn
{get; set;}
}
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;}
}
有适当的验证规则,因此一天内每种类型的事件不能超过一个。
我试着使用聚合函数,但我真的一事无成。
谢谢大家! 按
EventDate
date部分对时间事件进行分组。要实现这一点,您需要使用EntityFunctions.TruncateTime
方法(简单的EventDate.Date
将不适用于实体框架)
也可以用
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 :)
List timeEvents=new List();
//虚拟值。
DateTime now=DateTime.now;
对于(int i=0;i<8;i++)
{
添加(new TimeEvent(){Id=i,EventDate=now,CheckIn=false});
now=now.Add(TimeSpan.Parse(“3:1”);
添加(new TimeEvent(){Id=i,EventDate=now,CheckIn=true});
now=now+TimeSpan.Parse(“1”);
}
//分组
VarDataSet=timeEvents.GroupBy(a=>a.EventDate.Date);
列表差异=新列表();
foreach(数据集中的变量x)
{
如果(!(x.Count()==1))
{
Diff.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});
}
}
//差异列表已满。现在,您可以随意使用差异:)
无论创建什么聚合委托,都需要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;
}
}
}
静态IEnumerable getDiff(YourContext)
{
布尔?查克丁;
日期时间最后日期;
foreach(context.TimeEvents.OrderBy(te=>te.EventDate)中的var事件)
{
if((checkedIn.HasValue&&checkedIn.Value=!event.CheckIn)||
(!checkedIn.HasValue&&event.CheckIn))
{
if(checkedIn.HasValue&!event.CheckIn)
{
收益率-收益率新差异
{
CheckInTime=最后日期;
签出时间=event.EventDate;
};
}
checkedIn=event.CheckIn;
lastDate=event.EventDate;
}
}
}
这样,无论数据从何处开始,也不管它是否正确发送触发器。我还忽略了你虚假的
Diff.Date
属性。它不处理签入期间桥接日期边界。您是否尝试按EventDate.Date first对它们进行分组?@Bond-no。我没想过。我锁上了锁。我试试看。谢谢。这是一个很好的建议,特别是因为LINQ to Entities中不支持AFAIKAggregate
是每个TimeEvent
唯一的Id
还是外键?i、 e.您是否TimeEvents
?仅一个实例的实体日志数据?请向我们展示您失败的尝试,以便我们查看您的上下文。从问题中复制类定义有什么意义?实体的Linq在哪里?我改了。:)谢谢。我已经在TimeEvent的列表中查询了它,但仍然没有Linq to实体:)您正在使用Linq to对象。哦,我现在可以看到,我不能只在EventDate.Date
上分组。我仍然没有获得linq to entities和linq to objects:(是的,ElementAt
也不受linq to entities的支持。请参阅我将对TruncateTime
函数:)谢谢。我将尝试一下。做了一些修改,使其与SQL Server CE配合使用。谢谢@EladLachmi很高兴我帮助了你:)顺便问一下,你能告诉我SQL Server CE不支持哪个部分(只是为了将来知道)?EntityFunctions.TruncateTime
不适用于CE。我必须将组t按新的{t.EventDate.Day,t.EventDate.Month,t.EventDate.Year}使用到g
。通过这一修改,g.Key也解决了一个问题。既然我真的不需要它,我就把它扔了。