views:

230

answers:

2

Hello,

Can anyone tell me how to write the following query in Entity Framework 4.0? "Blogs" and "Categories" are my entities. The query basically returns me the list of categories and the number of blogs that are in that category.

SELECT b.CategoryId, c.Value, Count(b.Id) AS [Count] FROM dbo.Blogs b
INNER JOIN dbo.Categories c ON b.CategoryId = c.Id
GROUP BY b.CategoryId, c.Value

Thanks in advance.

A: 

If you have navigation properties in your entities, you can do that :

var cats = from c in db.Categories
           let count = c.Blogs.Count()
           where count > 0
           select new
           {
               CategoryId = c.Id,
               Value = c.Value,
               Count = count
           };

If you prefer to use an explicit join, you can do it like that :

var cats = from c in db.Categories
           join b in db.Blogs on c.Id equals b.CategoryId into g
           select new
           {
               CategoryId = c.Id,
               Value = c.Value,
               Count = g.Count()
           };
Thomas Levesque
Thanks for your reponse.
+1  A: 

The following should work (LinqToEntities):

var categories = from c in oc.Categories
                 select new
                 {
                     CategoryId = c.Id,
                     c.Value,
                     Count = c.Blogs.Count()
                 }

This will give you a list of category ids and values and for each category id you get the number of blogs in that category.

EDIT: To give an answer to the question in your comment: this isn't possible in LinqToEntities but you can do it in Entity SQL.

var results = new ObjectQuery<DbDataRecord>(
    @"SELECT y, COUNT(y)
      FROM MyEntities.Blogs AS b
      GROUP BY YEAR(b.CreatedDate) AS y", entities).ToList();
var nrBlogsPerYear = from r in results
                     select new { Year = r[0], NrBlogs = r[1] };

In the Entity SQL query, you should replace MyEntities with the name of your context.

EDIT: As I just found out through a comment by Craig, grouping by year is possible in L2E so you can write your query like this:

    var nrBlogsPerYear = from b in oc.Blogs
                         group b by b.CreatedDate.Year into g
                         select new { Year = g.Key, NrBlogs = g.Count() };
Ronald Wildenberg
Thank you! It worked perfectly. I didn't knew we can do "select new" without defining a class which has those properties.
Another quick question if you don't mind. How do I write a L2E query which returns the Year and the number of blogs for that year. Blog.CreatedDate has the date info and I'm looking for something like Year Count-----------2010 122009 45etc.. so I can display in UI like 2010 (12), 2009 (45) .. Thank you!
You can do the year grouping in L2E as well. [L2E supports the Year property](http://msdn.microsoft.com/en-us/library/bb738681.aspx)
Craig Stuntz
Cool, didn't know that. Thanks. I'll update my answer with this new info.
Ronald Wildenberg