views:

2179

answers:

2

I'm having difficulty translating sql to linq syntax.

I have 2 tables (Category and CategoryListing) which reference each other with CategoryID. I need to get a list of all the CategoryID in Category Table and the Count of CategoryID for all corresponding matches in the CategoryListing table. If a CategoryID is not present in CategoryListing, then the CategoryID should still be returned - but with a frequency of 0.

The following sql query demonstrates expected results:

SELECT c.CategoryID, COALESCE(cl.frequency, 0) as frequency
FROM Category c
LEFT JOIN (
    SELECT cl.CategoryID, COUNT(cl.CategoryID) as frequency 
    FROM CategoryListing cl
    GROUP BY cl.CategoryID
) as cl
ON c.CategoryID = cl.CategoryID
WHERE c.GuideID = 1
+3  A: 

Not tested, but this should do the trick:

var q = from c in ctx.Category
     join clg in 
      (
       from cl in ctx.CategoryListing
       group cl by cl.CategoryID into g
       select new { CategoryID = g.Key, Frequency = g.Count()}
      ) on c.CategoryID equals clg.CategoryID into cclg
     from v in cclg.DefaultIfEmpty()
     where c.GuideID==1
     select new { c.CategoryID, Frequency = v.Frequency ?? 0 };
Frans Bouma
Frans,Thanks for the quick reply. This works great except I need a left join on clg.
JWalker
I don't believe there's really any such thing as a left join in LINQ...
Neil Barnwell
Oh! my bad, will fix it. just a sec
Frans Bouma
Fixed it. It needed an into clause and a defaultifempty (which result in a groupjoin + defaultifempty call, two of my favorite things to hate about linq as they make writing a linq provider a true hell ;))
Frans Bouma
@Neil Barnwell: You can do left joins in linq by using join and on equals. For inner joins, instead of using the join keyword, you should use the relational ability of the objects.
achinda99
@achinda99: Can you provide an example using the relational ability of the objects?
JWalker
@JWalker: I think achinda99 means that if you do:from c in ctx.Customerfrom o in c.Ordersit will become a leftjoin if order.CustomerId is nullable. Though in your case that doesn't apply.
Frans Bouma
@Frans: Thank you for update. It worked like a charm with one modification - in the 1st select new, Frequency = (int?)g.Count().
JWalker
A: 

do you know how to convert this to VB. I dont know how to convert Frequency = v.Frequency ?? 0 to VB. So everytime I got error can not convert Nullable to System.Int32.

Phuong Nguyen