有没有办法减少数据库上的命中数

时间:2014-02-07 15:14:58

标签: sql-server database-administration c# linq

我是C#,ASP.NET MVC和SQL Server的新手,但我已经使用了这段代码

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);

现在它可以工作,但我7次点击数据库?有没有更好的方法呢? 它有多少性能问题

3 个答案:

答案 0 :(得分:1)

以下是我将如何处理这个问题,只是在不经常访问数据库的情况下。你可能还有其他一些改进,但这不是你要求的。

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);

formsList的列表声明表示将查询数据库一次并将结果存储在List对象中。从那里,您可以继续使用LINQ来打破您的数据。

答案 1 :(得分:0)

您的第三个到第六个查询可以从四个不同的计数转换为一个分组,用于捕获每个组的计数:

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 }];

答案 2 :(得分:0)

往返次数不一定是坏事。你有没有想过七次点击,看看他们是否真的花了很多时间?我的猜测是,他们不是,这意味着你没事(除非这将在一个非常高的网站上运行)。

另一种方法是编写一个T-SQL存储过程,该过程一次性返回所需的所有值。然后,您可以将结果捕获为对象,或仅仅是一个整数列表,或其他任何内容。