表中有如下所示的数据
RowId =11-11 08:50:48.243 2 A 2015-11- 08:51:01.433 3 B 2015-11-08:51:01.433 3 B 2015:11-11 08:50:48.243 2 A
试图按以下方式获取数据:
用户,日期,计数A 2015-11-11 2B 2015-11-11 1选择用户,日期,计数(用户)从Table1组按用户,日期
因为时间涉及到日期字段,所以它会返回我3行。如何在SQL和Linq中实现这一点。请给我建议。
编辑:
我可以在SQL中得到它。
从Table1组中按用户选择用户、强制转换(日期为日期)、计数(用户)、强制转换(日期为日期)
编辑:
添加linq查询
var details = db.table1.GroupBy( r => new { r.RowId,r.User,r.Date}) .Select(g => new {Name = g.Key,Count = g.Count()}).ToList();
发布于 2015-11-11 16:03:54
对于Linq查询,只需执行以下操作:(您需要使用System.Data.Entity.SqlServer
命名空间导入。
执行这个linq查询所有的计算都是在服务器数据库上完成的。注意,Table1s
代表Table1
的DbSet
,context
是您的DbContext
实例。
var query = from item in context.Table1s
group item by new
{
item.User,
Year = SqlFunctions.DatePart("yyyy", item.Date),
Month = SqlFunctions.DatePart("mm", item.Date),
Day = SqlFunctions.DatePart("dd", item.Date)
} into g
select new { g.Key.User, g.Key.Year, g.Key.Month, g.Key.Day, Count = g.Count() };
然后创建最后的结果如下:
var result = query.ToList().Select(p =>
new
{
p.User,
Date = new DateTime(p.Year.Value, p.Month.Value, p.Day.Value),
p.Count
}).ToList();
其他解决方案是创建一个DbContext将用于检索所需数据的SQL。SQL视图主体必须是您在问题中所写的SQL。
编辑2: DbFunctions
就像Cetin在注释中指出的那样,我们也可以使用System.Data.Entity.DbFunctions。而且代码比使用SqlFunctions.更干净。这将只适用于EF 6和更高版本。使用SqlFunctions的版本适用于EF 4和更高版本。
var query = from item in context.Table1s
group item by new
{
item.User,
Date = DbFunctions.TruncateTime(item.Date)
} into g
select new { g.Key.User, g.Key.Date, Count = g.Count() };
编辑1:这是特定于Cetin Basoz的回答:
众所周知,使用AsEnumerable并不能有效地完成所需的工作。他给我们的第二个解决办法是:
var grouped = from d in db.MyTable
group d by new {
User = d.User,
Date=d.Date.HasValue ? d.Date.Value.Date : (DateTime?)null} into g
select new {User=g.Key.User, Date=g.Key.Date, Count=g.Count()};
此解决方案只是不起作用,因为:
LINQ实体中不支持指定类型成员“Date”。只支持初始化器、实体成员和实体导航属性。
发布于 2015-11-11 15:29:03
如果时间是问题所在,您可以首先转换它:
select User, CAST(dateColumn AS DATE) as dateConverted
into #tempTable
from myTable
然后通过以下方式使用窗口函数或组:
select *,
count(user) over (partition by date) as userCount
from #tempTable
这应该适用于SQL服务器,不知道Linq
编辑:如果日期部分是问题,只需select into
从您的表到一个表的铸造日期。那么在Linq就不会有这个问题了。
发布于 2015-11-11 15:45:44
var grouped = from d in db.MyTable.AsEnumerable()
group d by new {
User = d.User,
Date=d.Date.HasValue ? d.Date.Value.Date : (DateTime?)null} into g
select new {User=g.Key.User, Date=g.Key.Date, Count=g.Count()};
迟早有人会说,这不是服务器端分组,会受到性能的影响,而且他们是对的。如果没有可枚举的,则它是服务器端的,但代价是每个组的另一个调用,因此这里有另一种方法:
public class MyResult
{
public string User {get;set;}
public DateTime? Date {get;set;}
public int Count {get;set;}
}
var grouped = db.ExecuteQuery<MyResult>(@"select [User],
Cast([Date] as Date) as [Date],
Count(*) as [Count]
from myTable
group by [user], Cast([Date] as Date)");
编辑:我不知道为什么以前我想的是另一种方式,这只会在服务器端工作,而不需要AsEnumerable():
var grouped = from d in db.MyTable
group d by new {
User = d.User,
Date=d.Date.HasValue ? d.Date.Value.Date : (DateTime?)null} into g
select new {User=g.Key.User, Date=g.Key.Date, Count=g.Count()};
https://stackoverflow.com/questions/33653762
复制相似问题