문제

I'm new to C#, ASP.NET MVC and SQL Server, but I have got this code working

DateTime startDate = DateTime.Parse(start);
DateTime endDate = DateTime.Parse(end);

ViewData["TotalDuringPeriod"] = db.AlcoholForms.Count(x => x.CreatedDate >= startDate && x.CreatedDate <= endDate);
ViewData["TotalUniqueClientsDuringPeriod"] = db.AlcoholForms.Where(x => x.CreatedDate >= startDate && x.CreatedDate <= endDate).Select(x => x.ClientId).Distinct().Count();
ViewData["TotalGateNew"] = db.AlcoholForms.Count(x => x.ReferredTo == "Gate" && x.Reengagement == false && (x.CreatedDate >= startDate && x.CreatedDate <= endDate));
ViewData["TotalGateReengagment"] = db.AlcoholForms.Count(x => x.ReferredTo == "Gate" && x.Reengagement && (x.CreatedDate >= startDate && x.CreatedDate <= endDate));
ViewData["TotalSwitchNew"] = db.AlcoholForms.Count(x => x.ReferredTo == "Switch" && x.Reengagement == false && (x.CreatedDate >= startDate && x.CreatedDate <= endDate));
ViewData["TotalSwitchReengagement"] = db.AlcoholForms.Count(x => x.ReferredTo == "Switch" && x.Reengagement && (x.CreatedDate >= startDate && x.CreatedDate <= endDate));

List<ReportAlcoholReferals> reportData = db.AlcoholForms.Where(x => x.Referral && (x.CreatedDate >= startDate && x.CreatedDate <= endDate)).Select(x => new ReportAlcoholReferals()
            {
                FirstName = x.Client.FirstName,
                LastName = x.Client.LastName,
                Date = x.CreatedDate,                 
                ClientId = x.ClientId,
                AlcoholForm = x
            }).OrderBy(x => x.AlcoholForm.ReferredTo).ToList();
            return View(reportData);

Now it works but I am hitting the database 7 times? Is there a better way of doing this? How much of a performance issue is it

도움이 되었습니까?

해결책

Here is how I would handle this, simply in the context of hitting the database less often. There are probably other improvements you could make as well, but that's not what you're asking for.

DateTime startDate = DateTime.Parse(start);
DateTime endDate = DateTime.Parse(end);
List<AlcoholForms> formsList = db.AlcoholForms.Where(x => x.CreatedDate >= startDate && x.CreatedDate <= endDate).ToList();

ViewData["TotalDuringPeriod"] = formsList.Count();
ViewData["TotalUniqueClientsDuringPeriod"] = formsList.Select(x => x.ClientId).Distinct().Count();
ViewData["TotalGateNew"] = formsList.Count(x => x.ReferredTo == "Gate" && x.Reengagement == false);
ViewData["TotalGateReengagment"] = formsList.Count(x => x.ReferredTo == "Gate" && x.Reengagement);
ViewData["TotalSwitchNew"] = formsList.Count(x => x.ReferredTo == "Switch" && x.Reengagement == false);
ViewData["TotalSwitchReengagement"] = formsList.Count(x => x.ReferredTo == "Switch" && x.Reengagement);
List<ReportAlcoholReferals> reportData = formsList.Where(x => x.Referral).Select(x => new ReportAlcoholReferals()
{
    FirstName = x.Client.FirstName,
    LastName = x.Client.LastName,
    Date = x.CreatedDate,                 
    ClientId = x.ClientId,
    AlcoholForm = x
}).OrderBy(x => x.AlcoholForm.ReferredTo).ToList();

return View(reportData);

The list declaration for formsList means that the database will be queried once and store the results in the List object. From there, you can continue to use LINQ to break out your data.

다른 팁

Your third through sixth queries can be turned from four different counts into one grouping that captures the count of each group:

var lookup = db.AlcoholForms.Where(x => x.CreatedDate >= startDate && 
        x.CreatedDate <= endDate)
    .GroupBy(x => new { x.ReferredTo, x.Reengagement },
        (key, items) => new{key, count = items.Count()})
    .ToDictionary(group => group.key, group => group.count);

ViewData["TotalGateNew"] = lookup[
    new { ReferredTo = "Gate", Reengagement = false }];
ViewData["TotalGateReengagment"] = lookup[
    new { ReferredTo = "Gate", Reengagement = true }];
ViewData["TotalSwitchNew"] = lookup[
    new { ReferredTo = "Switch", Reengagement = false }];
ViewData["TotalSwitchReengagement"] = lookup[
    new { ReferredTo = "Switch", Reengagement = true }];

The number of roundtrips is not necessarily a bad thing. Have you profiled the seven hits to see if they are really taking any time? My guess would be that they aren't, which means you're okay (unless this will be running on a very high volume site).

One alternative would be to write a T-SQL stored procedure that returns the all the values you need in one shot. You could then capture the result as an object, or just a list of ints, or whatever.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top