我有一个输出类的RSVP列表的方法。 RSVP基于来自保存RSVP记录的SQL表的拉取,基于类id的输入参数。然后制作一份所有学生的字典(RSVPd到该课程的人)。最后,我根据每个学生的数据输出了RSVP的IEnumerable。
我遇到的问题是我的数据中有几个学生是“坏用户”:他们不在系统中。可能是由于记录删除不良或创建不良。无论哪种方式,我都需要在构建IEnumerable时为“坏学生记录”设置错误处理。
我的想法是在评估此行上的学生ID时发现潜在的错误:
var data = x.ToRsvpData(students[x.RawAgentId]);
然后跳过该记录继续下一个记录。但是,我不知道该怎么做。
这是完整的方法:
public IEnumerable<RsvpData> GetAllRsvpsFor(Guid scheduledId)
{
var rsvps = _sors.AnyRsvpsIn(new[] { scheduledId })[scheduledId];
var certificates = _sors.CertificatesIn(rsvps.Select(x => x.RsvpId).ToList());
var students = _sors.StudentsBy(rsvps);
return rsvps.Select(x => {
var data = x.ToRsvpData(students[x.RawAgentId]);
if (x.Completed)
{
data.SignatureUrl = StaticContent.S3WebPrefixFor(string.Format("/schools/signatures/{0}.jpg", x.RsvpId.ToString()));
var cert = certificates.FirstOrDefault(c => c.Rsvp.RsvpId == x.RsvpId);
data.CertificateId = cert != null ? cert.CertId.ToString() : "";
}
return data;
}).OrderBy(x => x.LastName).ToList();
}
更新 : 这是完整的,有效的代码:
public IEnumerable<RsvpData> GetAllRsvpsFor(Guid scheduledId)
{
var rsvps = _sors.AnyRsvpsIn(new[] { scheduledId })[scheduledId];
var certificates = _sors.CertificatesIn(rsvps.Select(x => x.RsvpId).ToList());
var students = _sors.StudentsBy(rsvps);
var cleanRsvpData = new List<RsvpData>();
foreach (var rsvp in rsvps)
{
try
{
var data = rsvp.ToRsvpData(students[rsvp.RawAgentId]);
if (rsvp.Completed)
{
data.SignatureUrl = StaticContent.S3WebPrefixFor(string.Format("/schools/signatures/{0}.jpg", rsvp.RsvpId.ToString()));
var cert = certificates.FirstOrDefault(c => c.Rsvp.RsvpId == rsvp.RsvpId);
data.CertificateId = cert != null ? cert.CertId.ToString() : "";
}
cleanRsvpData.Add(data);
}
catch (Exception ex)
{ //Bad Student record
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
}
答案 0 :(得分:3)
根据使其成为特别行为不当的记录的原因,只需将Enumerable
包裹在另一个Enumerable
中即可解决问题。像这样:
IEnumerable<Record> GetCorrectRecords(IEnumerable<Record> records)
{
foreach(var record in records)
if(record.Valid) // up to you how you define this
yield return record;
}
答案 1 :(得分:1)
你可以使用着名的try ... catch块来做到这一点,如下所示:
public IEnumerable<int> GetAllRsvpsFor(Guid scheduledId)
{
//all the code that precedes the loop
//for or foreach loop
{
//any code that you have to perform after this block
try
{
var data = x.ToRsvpData(students[x.RawAgentId]);
}
catch
{
continue; //continues to the next for iteration in case of any error
}
//any code that you have to perform after this block
}
}
答案 2 :(得分:1)
不是使用lambda表达式,最好的办法是使用临时列表变量并使用try catch块 - 所以只有“干净”的记录才能进入你的列表:
List<RsvpData> cleanRsvpData = new List<RsvpData>();
foreach (RsvpData rsvp in rsvps)
{
try
{
RsvpData data = rsvp.ToRsvpData(students[x.RawAgentId]);
if (rsvp.Completed)
{
data.SignatureUrl = "test";
var cert = certificates.FirstOrDefault(c => c.Rsvp.RsvpId == x.RsvpId);
data.CertificateId = cert != null ? cert.CertId.ToString() : "";
}
cleanRsvpData.Add(data);
}
catch (Exception ex)
{ // handle error here
}
}
由于try catch是INSIDE循环,如果列表中的某个项引发错误,它将不会破坏整个循环。