Performance shifting for SQL Database and Linq memory grouping
It's hard to tell if this will work without trying it but I'd at least give this a shot. By calling ToList on your calls, visits and visitors and then concating them you are losing the database query structure, try this instead:

            using (var db = new Track_LOpEntities())
            {
                var visitors = db.JTrack_Visitors.AsNoTracking()
                    .Where(v =&gt; v.CreatedOn &gt;= start &amp; v.CreatedOn &lt;= end)
                    .Select(v =&gt; new DashHelper() { DateAndTime = v.CreatedOn.Value, Source = 1 });

                var visits = db.JTrack_Visits.AsNoTracking()
                    .Where(v =&gt; v.DateTimeStart &gt;= start &amp; v.DateTimeStart &lt;= end)
                    .Select(v =&gt; new DashHelper() { DateAndTime = v.DateTimeStart.Value, Source = 2 });

                var calls = db.JTrack_Calls.AsNoTracking()
                    .Where(v =&gt; v.calldate &gt;= start &amp; v.calldate &lt;= end)
                    .Select(v =&gt; new DashHelper() { DateAndTime = v.calldate.Value, Source = 3 });
               var totals = visits.Union(calls).Union(visitors);
               var visitorsGroup = totals.GroupBy(q =&gt; new { q.DateAndTime.Date, q.DateAndTime.Hour });

        List&lt;DashGraph&gt; dg = new List&lt;DashGraph&gt;();

        foreach (var g in visitorsGroup)
        {
            dg.Add(new DashGraph()
            {
                Date = g.Key.Date,
                Hour = g.Key.Hour,
                TotalVisitors = g.Where(x =&gt; x.Source == 1).Count(),
                TotalPageViews = g.Where(x =&gt; x.Source == 2).Count(),
                TotalCalls = g.Where(x =&gt; x.Source == 3).Count()
            });
        }

            }


Also I'm not sure why you need a transaction scope, your not doing any updates.