For Linq Query just do the following: (you need to import using System.Data.Entity.SqlServer
namespace.
Execute this linq query all calculations are done on the server database. Notice that Table1s
represents the DbSet
for Table1
and context
is your DbContext
instance.
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() };
Then create the final result like this:
var result = query.ToList().Select(p =>
new
{
p.User,
Date = new DateTime(p.Year.Value, p.Month.Value, p.Day.Value),
p.Count
}).ToList();
Other solution is to create a SQL View that will be used by DbContext to retrive the data you want. The SQL View body must be the SQL your wrote in your question.
EDIT 2 : DbFunctions
Like Cetin Basoz pointed in comments we can use System.Data.Entity.DbFunctions as well. And the code is more cleaner than using SqlFunctions. This will work only with EF 6 and greater. The version using SqlFunctions work with EF 4 and greater.
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() };
EDIT 1 : this is specific for Cetin Basoz's answer :
As we all know using AsEnumerable is not efficient for doing what is needed.
The second solution he gives us which is :
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()};
This solution just not work because of this :
The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.