1
\$\begingroup\$

I'd like to know if there's any better way to write this query:

(from a in Context.Pages
join b in Context.Visitors on a.PageID equals b.PageFK
join c in Context.Visits on b.VisitorID equals c.VisitorFK
join d in Context.Signups on c.VisitID equals d.VisitFK
where
d.DateOptinUtc.HasValue && a.UserFK == USER_ID
group d by new { a.PageID, a.DateCreated, a.BaseName, a.Name }
into g
select
new ListReport
 {
     DateCreated = g.Key.DateCreated,
     BaseName = g.Key.BaseName,
     Id = g.Key.PageID,
     Name = g.Key.Name,
     Optins = g.Count(),
     Views =
         (from h in Context.Visits
          where
              h.Visitors.PageFK == g.Key.PageID
          select h).Count()
 }).AsQueryable();

Are there any performance issues writing subqueries like these? I don't how I can get that value from the groupby.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Doesn't necessarily look bad. What does the generated SQL look like? EF may have optimized this pretty well and the database's query optimizer may further optimize it. Is there a performance problem at all? \$\endgroup\$ Commented Apr 16, 2014 at 7:46
  • \$\begingroup\$ There is no performance problem atm as we are in development stage. I was just curious / want to know it there was a better way. Thanks! \$\endgroup\$ Commented Apr 16, 2014 at 12:13
  • \$\begingroup\$ A (micro) optimization might be to collect the page counts separately and join these in memory with your query. \$\endgroup\$ Commented Apr 16, 2014 at 12:38

1 Answer 1

1
\$\begingroup\$

Aside from the performance issues you should make the query more readable by using relevant variable names instead of a, b, c, d, g, and h. In addition, the ambiguous ListReport class name should be changed to something more specific like PageUsage since it contains information about a page and how many times it has been viewed/used for signup.

(from page in Context.Pages
join visitor in Context.Visitors on page.PageID equals visitor.PageFK
join visit in Context.Visits on visitor.VisitorID equals visit.VisitorFK
join signup in Context.Signups on visit.VisitID equals signup.VisitFK
where
signup.DateOptinUtc.HasValue && page.UserFK == USER_ID
group signup by new { page.PageID, page.DateCreated, page.BaseName, page.Name }
into signupsByPage
select
new PageUsage
 {
     DateCreated = signupsByPage.Key.DateCreated,
     BaseName = signupsByPage.Key.BaseName,
     Id = signupsByPage.Key.PageID,
     Name = signupsByPage.Key.Name,
     Optins = signupsByPage.Count(),
     Views =
         (from subVisit in Context.Visits
          where
              subVisit.Visitors.PageFK == signupsByPage.Key.PageID
          select subVisit).Count()
 }).AsQueryable();
\$\endgroup\$
2
  • \$\begingroup\$ Is there a way to modify this query to bring every record on table Pages? I tried to use defaultifempty thing but did not work as expected. \$\endgroup\$ Commented Apr 17, 2014 at 14:51
  • \$\begingroup\$ It worked now but if i use any where clause using signup it stops working \$\endgroup\$ Commented Apr 17, 2014 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.