2015-11-11 242 views
2

我有一个表中的数据如下集团通过与多列

RowId | User | Date 
-------------------------- 
    1  A  2015-11-11 08:50:48.243 
    2  A  2015-11-11 08:51:01.433 
    3  B  2015-11-11 08:51:05.210 

试图让数据如下:

User, Date,  Count 
    A 2015-11-11  2 
    B 2015-11-11  1 

Select User,Date,Count(User) from Table1 
Group By User,Date 

它返回我由于日期字段中涉及时间,因此有3行。 如何在SQL和LINQ得到这个。 请给我建议。

编辑:

我能得到它的SQL

Select User,Cast(Date as Date),Count(User) from Table1 
Group By User,Cast(Date as Date)  

编辑:

添加LINQ查询

var details = db.table1.GroupBy(r => new { r.RowId,r.User,r.Date}) 
.Select(g => new {Name = g.Key, Count = g.Count()}).ToList(); 
+0

编辑该问题。在linq中需要帮助 – user1893874

+0

linq查询在哪里?即显示您尝试过的内容。 –

+0

请添加您当前拥有的LInQ代码,以便我们对其进行修改 – Behrooz

回答

0

对LINQ查询只是做了以下内容:(你需要使用System.Data.Entity.SqlServer命名空间导入

执行此LINQ查询所有的计算都在服务器数据库上完成。请注意,Table1s表示DbSetTable1context是你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(); 

其他的解决方案是创建一个SQL视图,将通过的DbContext使用以检索所需的数据。 SQL视图正文必须是您在问题中写入的SQL。

编辑2:DbFunctions

像切廷Basoz在评论中指出,我们可以使用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:这是具体的切廷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是不支持的实体。仅支持初始化程序,实体成员和实体导航属性。

+0

尽管这被标记为答案,你是否尝试过这一个?这将如何与可以为空的日期列(日期/日期时间列常见)配合使用。否则,我可以用d,Date.Date简单地完成原始的工作,然后移除AsEnumerable。 –

+0

再次思考并重新测试,我根本不需要AsEnumerable,它在服务器端运行正常。我不知道为什么我在第一次测试中看到发送给服务器的多个查询(必须留下一些代码)。 –

+0

然后只需编辑你的答案。停止淹没其他职位。这不是一个compétition,并解释了为什么你不需要AsEnumerable。谢谢 – CodeNotFound

0

如果时间问题,你可以先转换它:

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中遇到这个问题。

+0

我不需要为此创建临时表。检查问题。用户已经为TSQL – CodeNotFound

+0

提供了一个解决方案,他在我写回应之后添加了解决方案。 – CM2K

+0

是的,我需要Linq的帮助。 – user1893874

0
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()}; 
+0

你可以做的只是一个电话到服务器端像我在我的答案和没有Enumerable。 – CodeNotFound

+0

谢谢您的建议和答复。 – user1893874

+0

如果您认为datetime列可能接受NULL值,那么使用SqlFunctions将不起作用。 –