嗨我想将组数据返回到ui层。
这里是我想如何简化groupby“GenerationDate”并返回List<>中的数据回到UI gridview。 我觉得这很麻烦,因为我做了forloop。同样在UI层,我必须为这个简单的groupby做另一个forloop。你能帮忙简化一下吗?
public List<SalaryTracker> GetSalaryTrackerOrderByGenerationDate(int tutorId)
{
List<SalaryTracker> salary = new List<SalaryTracker>();
using (leDataContext db = new leDataContext())
{
try
{
var r =
from s in db.SalaryTrackers
where s.StaffId == 2 && s.PaymentDate == null
group s by s.GenerationDate into g
where g.Count() > 0
select new
{
date = g.Key, totalSalary = g.Sum(p => p.SalaryAmount)
};
foreach (var rr in r)
{
SalaryTracker m = new SalaryTracker();
m.GenerationDate = rr.date;
m.SalaryAmount = rr.totalSalary;
salary.Add(m);
}
return salary;
}
catch (Exception ex)
{
Logger.Error(typeof(SalaryTracker), ex.ToString());
throw;
}
}
}
--------------- GUI
totalCommissionsGroup = salary.GetSalaryTrackerOrderByGenerationDate(tutor.Id);
IList<SalaryTracker> rr = (
totalCommissionsGroup.GroupBy(x => x.GenerationDate)
.Select(g => new SalaryTracker
{
MonthId = g.Key.Month,
MonthToPay = common.GetMonthName(Convert.ToInt16(g.Key), true),
SalaryAmount = g.Sum(x => x.SalaryAmount)
})).ToList<SalaryTracker>();
gvSalaryPayment.DataSource = rr;
我这样做,以便我可以在字符串
中获得MonthToPay答案 0 :(得分:2)
public List<SalaryTracker> GetSalaryTrackerOrderByGenerationDate(int tutorId)
{
using (var db = new leDataContext())
{
try
{
return (
from s in db.SalaryTrackers
where s.StaffId == 2 && s.PaymentDate == null
group s by s.GenerationDate into g
select new
{
MonthId = g.Key.Month,
// I don't know what "common" is in your UI code,
// I am just using GetMonthName here
MonthToPay = GetMonthName(Convert.ToInt16(g.Key), true),
SalaryAmount = g.Sum(p => p.SalaryAmount)
})
.AsEnumerable()
.Select(x => new SalaryTracker
{
MonthId = x.MonthId,
MonthToPay = x.MonthToPay,
SalaryAmount = x.SalaryAmount
})
.ToList();
}
catch (Exception ex)
{
Logger.Error(typeof(SalaryTracker), ex.ToString());
throw;
}
}
}
答案 1 :(得分:0)
我同意Mahesh Velaga的重构(+1),我想补充一点,应用程序的那个级别的日志记录错误是不寻常的。特别是当你决定以任何方式重新抛出异常时。因此,我建议您删除带有错误日志记录的完整try catch
,并仅在应用程序的根目录中记录(如果您还没有这样做)。这使您的代码更加清晰。
当你这样做的时候,你会发现剩下的是一个很好的可读方法,除了业务逻辑之外别无其他任何东西。
的更新强> 的
但如果我们不把'试试' 在datamodel层,怎么会 主调用者捕获错误?我有 多年来一直在使用这种模式.. 如果我错了,请纠正我。参考 这个link。
按照您提供的referenced article中所示的方式,按照您提供的方式进行操作几乎总是次优的,原因如下:
这并不意味着您无法向用户显示任何错误信息,而只会对您明确抛出以向用户显示错误信息的异常执行此操作。例如:
try
{
// Call into service layer
}
catch (BusinessLayerException ex)
{
this.ValidationSummary1.Add(new CustomValidator
{
ErrorMessage = ex.Message, IsValid = false
});
}
在此示例中,BusinessLayerException
是从业务层抛出的特殊异常,其中包含可供用户理解的错误消息(如果多个用户使用您的应用程序,可能会出现本地化错误消息)语言)。
对于所有其他异常,大多数情况下您不希望向用户显示确切的错误消息,因为您不知道出了什么问题以及错误有多严重以及异常包含哪些信息。最好的办法是在表示层中尽可能减少错误处理逻辑,并在应用程序顶层的一个位置处理它。在这种情况下,您可以确保在这种情况下向用户显示错误页面,并确保将错误记录到日志系统中。
您可以configure ASP.NET在出现错误时显示自定义错误页面。这是一个例子:
<customErrors mode="RemoteOnly"
defaultRedirect="~/ErrorPage.htm">
</customErrors>
ErrorPage.htm
可以显示一般信息,例如Stackoverflow上的一般“它是我们的错误”错误页面。也许一些支持的联系信息,您的家庭电话号码,以便他们可以在晚上给您打电话; - )
通过在global.asax中实现Application_Error
方法,您可以在应用程序日志中的单个位置处理未处理的异常:
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
// Log the exception here.
}
确保记录有关所需错误的信息,例如堆栈跟踪,错误消息,异常类型以及可能发生的所有内部异常。
我希望这会有所帮助。