我有这个项目,我正在努力。在索引视图中,我必须显示许多可能不相关的数据。目前我在控制器中的索引动作看起来完全搞砸了,因为我可以说我已经以非常业余的方式完成了它。我已经阅读了很多关于ViewBag的使用情况,有些人甚至说应该避免完全使用它并使用ViewModel代替。我一直在实现ViewModel,我理解它的用处,我很欣赏它。但是在这个项目中,我不知道如何将我的请求转换为一个视图模型,因为我查询的是一些不相关的模型,所以我无法开始使用join语句。见下面的代码
public ActionResult Index()
{
var db = new ApplicationDbContext();
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
var CurrentUser = manager.FindById(User.Identity.GetUserId());
/*******counts of loans*******/
var PendingCounts = db.Transaction.Where(t => t.Status.Status == "Pending" && t.AgentId == CurrentUser.SalesAgent.AgentId).Count();
var DeclinedCounts = db.Transaction.Where(t => t.Status.Status == "Declined" && t.AgentId == CurrentUser.SalesAgent.AgentId).Count();
var ApprovedCounts = db.Transaction.Where(t => t.Status.Status == "Approved" && t.AgentId == CurrentUser.SalesAgent.AgentId).Count();
ViewBag.PendingCounts = PendingCounts;
ViewBag.DeclinedCounts = DeclinedCounts;
ViewBag.ApprovedCounts = ApprovedCounts;
/***Percentage of pending, approved and declined loans in counts******/
decimal PendingCount = (decimal)PendingCounts;
decimal DeclinedCount = (decimal)DeclinedCounts;
decimal ApprovedCount = (decimal)ApprovedCounts;
decimal sum = PendingCount + DeclinedCount + ApprovedCount;
decimal PendingPercent = (PendingCount / sum) * 100;
decimal DeclinedPercent = (DeclinedCount / sum) * 100;
decimal ApprovedPercent = (ApprovedCount / sum) * 100;
ViewBag.PendingPercent = PendingPercent;
ViewBag.DeclinedPercent = DeclinedPercent;
ViewBag.ApprovedPercent = ApprovedPercent;
/****Value of loans******/
//select SUM(AmountRequested) as totalPending from Transactions where StatusId = 1;
var ValuePending = db.Transaction.Where(t => t.AgentId == CurrentUser.SalesAgent.AgentId && t.Status.Status == "Pending").Select(t => (decimal?)t.AmountRequested).Sum() ?? 0;
var ValueApproved = db.Transaction.Where(t => t.AgentId == CurrentUser.SalesAgent.AgentId && t.Status.Status == "Approved").Select(t => (decimal?)t.AmountApproved).Sum() ?? 0;
var ValueDeclined = db.Transaction.Where(t => t.AgentId == CurrentUser.SalesAgent.AgentId && t.Status.Status == "Declined").Select(t => (decimal?)t.AmountRequested).Sum() ?? 0;
ViewBag.ValuePending = ValuePending;
ViewBag.ValueApproved = ValueApproved;
ViewBag.ValueDeclined = ValueDeclined;
var thisDate = DateTime.Now;
var starting = new DateTime(thisDate.Year, thisDate.Month, 1);
var ending = starting.AddMonths(1);
var SpecifiedTotal = (from t in db.Transaction
where t.AgentId == CurrentUser.SalesAgent.AgentId
&& t.Status.Status == "Approved"
&& t.DateApproved >= starting && t.DateApproved < ending
select (decimal?)t.AmountApproved).Sum() ?? 0;
var MonthlyTarget = db.SalesAgent.Where(t => t.AgentId == CurrentUser.SalesAgent.AgentId).Select(t => (decimal)t.MonthlyTarget).FirstOrDefault();
var today = DateTime.Now;
var year = DateTime.Now.Year;
var month = DateTime.Now.Month;
var day = DateTime.Now.Day;
var NoOfDays = DateTime.DaysInMonth(year, month);
var start = today;
var stop = new DateTime(year, month, NoOfDays);
int WorkingDaysLeft = GetNumberOfWorkingDays(start, stop);
decimal RunRate = Math.Round((MonthlyTarget - SpecifiedTotal) / WorkingDaysLeft, 2);
ViewBag.RunRate = RunRate.ToString("N0");
/***Get initials of current user*///
var firstname = db.SalesAgent.Where(s => s.AgentId == CurrentUser.SalesAgent.AgentId).Select(s => s.AgentFirstName.Substring(0, 1)).SingleOrDefault();
var lastname = db.SalesAgent.Where(s => s.AgentId == CurrentUser.SalesAgent.AgentId).Select(s => s.AgentLastName.Substring(0, 1)).SingleOrDefault();
//ViewBag.firstnameletter = firstnameletter;
//ViewBag.lastnameletter = lastnameletter;
return View();
}
正如您所看到的,我已经将大量数据填充到ViewBag中,因为我需要在我的视图中显示它,例如我的视图看起来像这样
@{
ViewBag.Title = "Home Page";
}
<div class="imagecircle">
@ViewBag.firstnameletter @ViewBag.lastnameletter
</div>
<div class="row searchForm">
<form action="/Home/Index" method="post">
<div class="col-lg-3">
<label>Start</label>
<input type="date" class="StartDate form-control" name="StartDate" />
</div>
<div class="col-lg-3">
<label>End</label>
<input type="date" class="EndDate form-control" name="EndDate" />
</div>
<input type="submit" value="Search" class="submit btn btn-default " />
</form>
</div>
<div class="row header">
<div class="col-lg-3 section">
<div class="row">
<div class="col-lg-8">
<h4><span class="countNumber">@ViewBag.PendingCounts</span></h4> Transaction(s) Pending
<h4> <span class="countNumber">@ViewBag.PendingPercent</span>%</h4> Transaction(s) Pending
<h4><span class="countNumber">@ViewBag.ValuePending</span></h4> in value so far
</div>
<div class="col-lg-4 countHeader">
<i class="fa fa-spinner fa-spin"></i>
<h5>Pending</h5>
</div>
</div>
</div>
<div class="col-lg-3 section">
<div class="row">
<div class="col-lg-8">
<h4><span class="countNumber">@ViewBag.ApprovedCounts</span></h4> Transaction(s) Approved
<h4><span class="countNumber">@ViewBag.ApprovedPercent</span>%</h4> Transaction(s) Approved
<h4><span class="countNumber">@ViewBag.ValueApproved</span></h4> in value so far
</div>
<div class="col-lg-4 countHeader">
<i class="fa fa-check-circle-o"></i>
<h5>Approved</h5>
</div>
</div>
</div>
<div class="col-lg-3 section">
<div class="row">
<div class="col-lg-8">
<h4><span class="countNumber">@ViewBag.DeclinedCounts</span></h4> Transaction(s) Declined
<h4><span class="countNumber">@ViewBag.DeclinedPercent</span>%</h4> Transaction(s) Declined
<h4><span class="countNumber">@ViewBag.ValueDeclined</span></h4> in value so far
</div>
<div class="col-lg-4 countHeader">
<i class="fa fa-remove"></i>
<h5>Declined</h5>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 RunRate">
<p><sup><i class="fa fa-exclamation-circle"></i></sup>Run Rate = ₦ @ViewBag.RunRate</p>
<p>This is the amount you should get disbursed daily in order to meet your target this month.</p>
</div>
</div>
因为我需要对查询结果进行大量计算,所以我发现很难使用ViewModel,因此我坚持使用ViewBag。我知道这远非专业,因为它看起来不干净和光滑。我想我会尝试重构那些我期待单个结果进入方法的单个查询,但您认为我需要对上面的代码做些什么改进?帮助代码示例。
答案 0 :(得分:1)
ViewModels存储视图所需的表示逻辑。
虽然我质疑为什么许多计算不属于模型本身,但我将其作为重构练习,将业务逻辑从视图模型中移除到模型中。
此外,我将重构视图以使用viewmodel作为读者的练习。
以下是您的资料的视图模型示例:
public class TransactionViewModel
{
public TransactionViewModel(
List<Transaction> transactions,
SalesAgent salesAgent)
{
Transactions = transactions;
SalesAgent = salesAgent;
}
public List<Transaction> Transactions { get; set; }
public SalesAgent SalesAgent { get; set; }
public decimal MonthlyTarget
{
get { return (decimal) SalesAgent.MonthlyTarget; }
}
public string SalesAgentInitials
{
get
{
return
string.Format(
"{0}.{1}.",
SalesAgent.FirstName.First(),
SalesAgent.LastName.First());
}
}
public IEnumerable<Transaction> ApprovedTransactions
{
get { return Transactions.Where(t => t.Status.Status == "Approved"); }
}
public IEnumerable<Transaction> PendingTransactions
{
get { return Transactions.Where(t => t.Status.Status == "Pending"); }
}
public IEnumerable<Transaction> DeclinedTransactions
{
get { return Transactions.Where(t => t.Status.Status == "Declined"); }
}
public int ApprovedCount
{
get { ApprovedTransactions.Count(); }
}
public int PendingCount
{
get { PendingTransactions.Count(); }
}
public int DeclinedCount
{
get { DeclinedTransactions.Count(); }
}
public int TotalCount
{
get { return Transactions.Count; }
}
public decimal ApprovedPercent
{
get { return (decimal) ApprovedCount / TotalCount }
}
public decimal PendingPercent
{
get { return (decimal) PendingCount / TotalCount }
}
public decimal DeclinedPercent
{
get { return (decimal) DeclinedCount / TotalCount }
}
public decimal ApprovedValue
{
get { return ApprovedTransactions.Select(t => (decimal?)t.AmountRequested).Sum() ?? 0; }
}
public decimal PendingValue
{
get { return PendingTransactions.Select(t => (decimal?)t.AmountRequested).Sum() ?? 0; }
}
public decimal DeclinedValue
{
get { return DeclinedTransactions.Select(t => (decimal?)t.AmountRequested).Sum() ?? 0; }
}
public DateTime StartMonth
{
get { return new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1); }
}
public DateTime EndMonth
{
get { return StartMonth.AddMonths(1); }
}
public int DaysInMonth
{
get { return (EndMonth - StartMonth).Days; }
}
public int WorkingDaysLeftInMonth
{
get
{
Enumerable
.Range(DateTime.Today.Day, DaysInMonth)
.Select(d => new DateTime(DateTime.Today.Year, DateTime.Today.Month, d))
.Count(date =>
date.DayOfWeek != DayOfWeek.Saturday &&
date.DayOfWeek != DayOfWeek.Sunday);
}
}
public decimal SpecifiedTotal
{
get
{
return
ApprovedTransactions
.Where(t => t.DateApproved >= StartMonth && t.DateApproved < EndMonth)
.Select(t => (decimal?) t.AmountApproved)
.Sum() ?? 0;
}
}
public decimal RunRate
{
get { return Math.Round((MonthlyTarget - SpecifiedTotal) / WorkingDaysLeftInMonth, 2); }
}
public string RunRateFormat
{
get { return RunRate.ToString("N0"); }
}
}
这简化了行动:
public ActionResult Index()
{
var db = new ApplicationDbContext();
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
var CurrentUser = manager.FindById(User.Identity.GetUserId());
var loans =
db.Transaction
.Where(t =>
t.AgentId == CurrentUser.SalesAgent.AgentId)
.ToList();
var salesAgent =
db.SalesAgent
.FirstOrDefault(s => s.AgentId == CurrentUser.SalesAgent.AgentId);
var viewModel = new TransactionViewModel(loans, salesAgent)
return View(viewModel);
}