views:

406

answers:

2

I am writing a query where I want to count the number of times our call center gets contacted by date. Seems easy enough, but since the contact date field is a datetime field I get the time, so when I group by contact date(time) each contact date instance has a count of '1'. So, I want to group by just the date without the time. Below is the expression I use to query the database:

MyDataContext db = new MyDataContext();
var items = (from h in db.ContactHistories
             group h by h.contact_dt into g
             orderby g.Key
             select new
             {
                 contact_dt = g.Key,
                 item_count = g.Count()
             }).Take(50);

I've tried to use

     h.contact_dt.ToShortDateString()

But that doesn't work since SQL does know about ToShortDateString(). Any thoughts are greatly appreciated.

Thanks!

EDIT:

The .Take(50) is in place to limit the number of records I get until I add the date pickers and a where clause so I don't get all 400K records. ;)

+11  A: 

Use the Date property:

group h by h.contact_dt.Date into g

LINQ to SQL knows about that - see this handy page of "understood" methods and properties.

EDIT: Okay, so grouping directly doesn't work... how about we try to give it a bit of help:

var items = (from h in db.ContactHistories
             select h.Date into date
             group date by date into g
             orderby g.Key
             select new
             {
                 contact_dt = g.Key,
                 item_count = g.Count()
             }).Take(50);

I don't know if it'll work, but it's worth a try...

Jon Skeet
@Jon Skeet it does the default type for a DateTime (SQL) is a DateTime (.NET)
msarchet
See http://msdn.microsoft.com/en-us/library/bb882657.aspx for a list of all supported DateTime methods for LINQ to SQL
Hightechrider
@Hightechrider: That's great, thanks. Didn't know about it before. Will edit to promote the link...
Jon Skeet
@msarchet: I knew it would go to a DateTime and thus the change would *compile* - whether it would *work* is a different matter. But it sounds like it will :)
Jon Skeet
I tried that, but now I get 'The group by operation contains an expression that cannot be translated'.
Andy Evans
Does group by .DayOfYear work? If not, I would go for a database view instead of trying it in LinQ. The view would probably be more performant in any case.
Ope
@Andy: I've given another possible option...
Jon Skeet
@Jon: select-into, whoa that's a first for me. Would you happen to know of anything documenting that? Can't find anything that mentions usage such as that. Closest I could find is in the [into](http://msdn.microsoft.com/en-us/library/bb311045.aspx) reference but that's it.
Jeff M
@Jeff: That's exactly it. "The into contextual keyword can be used to create a temporary identifier to store the results of a group, join or select clause into a new identifier." In this case it's a select clause. It effectively just joins two queries together. You can read more about it in the C# spec, section 17.6.2.5 (C# 4 spec).
Jon Skeet
@Jon: I guess I'm just surprised that it's hard to find a blog or something that mentions and uses it. People are good at finding these kind of things and posting about it in detail.
Jeff M
@Jeff: Query continuations for select are used *relatively* rarely. Maybe I'll write a post about it on the train though, just for future reference :)
Jon Skeet
Shouldn't the inline query (or whatever that thing is called) `date` be called `dates` just for correctness? You're creating a collection of dates, aren't you?
Lasse V. Karlsen
@Jeff: Blogged about this in http://msmvps.com/blogs/jon_skeet/archive/2010/09/15/query-expression-syntax-continuations.aspx
Jon Skeet
@Lasse: It's awkward, in terms of pluralisation. The query continuation is creating a new range variable, which will only refer to a *single* entry at a time, not a group of them.
Jon Skeet
Ah, ok, hm, I see, never mind then :)
Lasse V. Karlsen
How would you put it in method syntax?
Josh
@Josh: I wouldn't :) Seriously, if I had to I'd basically work out what the C# compiler would translate it into... is there any particular bit that confounds you?
Jon Skeet
@Jon: Nothing so, just was wondering how to put that in method syntax. I always prefer method syntax to query syntax (personal preference).
Josh
+3  A: 

Use the .Date property of the DateTime object.

James Curran