Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 处理中等csv报告中的数据质量问题。最佳做法 需要一个更好的练习问题的帮助_C#_Design Patterns_Azure Functions - Fatal编程技术网

C# 处理中等csv报告中的数据质量问题。最佳做法 需要一个更好的练习问题的帮助

C# 处理中等csv报告中的数据质量问题。最佳做法 需要一个更好的练习问题的帮助,c#,design-patterns,azure-functions,C#,Design Patterns,Azure Functions,我有一个azure函数,它将不同API中的数据进行匹配,以创建最终的csv报告。我有一个60k-100k的柱状图和30根柱子 为了便于解释,我将使用一个小的学校示例 公立学生{ 字符串级别{get;set;} Name LegName{get;set;} 字符串父名称{get;set;} 字符串教师ID{get;set;} 字符串SchoolId{get;set;} } 公共名称{ 字符串名{get;set;} 字符串LastName{get;set;} } 在构建报告之前,我从两个公开学校和

我有一个azure函数,它将不同API中的数据进行匹配,以创建最终的csv报告。我有一个60k-100k的柱状图和30根柱子

为了便于解释,我将使用一个小的学校示例

公立学生{
字符串级别{get;set;}
Name LegName{get;set;}
字符串父名称{get;set;}
字符串教师ID{get;set;}
字符串SchoolId{get;set;}
}
公共名称{
字符串名{get;set;}
字符串LastName{get;set;}
}
在构建报告之前,我从两个公开学校和教师信息的API创建了两个
字典
。当然,还有来自学生API的
Student
列表。我无法控制这个trhee API、设计、数据质量,什么都没有

现在,当我有了所有的数据后,我开始创建报告

string GenerateTXT(字典学校、字典教师、学生){
StringBuilder内容=新建StringBuilder();
foreach(学生中的var学生){
content.Append($“{student.Grade}\t”);
Append($“{student.LegName.FirstName}\t”);
Append($“{student.LegName.LastName}\t”);
content.Append($“{schools.TryGetValue(student.TeacherId)}\t”);
content.Append($“{teachers.TryGetValue(student.SchoolId)}t”;
content.Append($“{student.FatherNme}\t”);
content.AppendLine();
}
返回content.ToString();
}
现在问题来了。我开始注意到数据质量问题,所以函数开始抛出异常。例如,没有有效学校或老师的学生,或者没有名字的学生。我尝试解决预期的场景和异常处理

string GenerateTXT(字典学校、字典教师、学生){
StringBuilder内容=新建StringBuilder();
var值=string.Empty;
foreach(学生中的var学生){
试一试{
content.Append($“{student.Grade}\t”);
Append($“{student.LegName.FirstName}\t”);
Append($“{student.LegName.LastName}\t”);
if(teachers.TryGetValue(student.TeacherId))
content.Append($“{teachers[student.TeacherId]}\t”);
其他的
content.Append($“\t”);
if(schools.TryGetValue(student.SchoolId))
content.Append($“{schools[student.SchoolId]}\t”);
其他的
content.Append($“\t”);
content.Append($“{student.FatherNme}\t”);
content.AppendLine();
}
捕获(例外情况除外){
log.Error($“读取worker{student.FirstName}时出错”);
}
}
返回content.ToString();
}
问题是,当发生意外错误时,我会停止阅读下一列可能有的数据,而跳转到下一个工作人员。因此,如果某个学生由于某种随机原因没有名字,那么报告中的那一行只会有分数,而没有其他内容,但我实际上拥有其余的数据值。所以问题来了。我可以在每一列上放置一个
try catch
,但请记住,我的真实场景有大约30列,可能更多……所以我认为这是一个非常糟糕的解决方案。有没有一种模式可以更好地解决这个问题


提前感谢!所以我要给你的第一点建议是使用。这是一个经过验证的库,因为它可以处理所有你永远不会想到的边缘情况。因此,请尝试一下:

public class Student
{
    public string Grade { get; set; }
    public Name LegName { get; set; }
    public string FatherName { get; set; }
    public string TeacherId { get; set; }
    public string SchoolId { get; set; }
}

public class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class NormalizedData
{
    public string Grade { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string School { get; set; }
    public string Teacher { get; set; }
    public string FatherName { get; set; }
}

static void GenerateCSVData(CsvHelper.CsvWriter csv, Dictionary<string, string> schools,
    Dictionary<string, string> teachers, Student[] students)
{
    var normalizedData = students.Select(x => new NormalizedData
    {
        Grade = x.Grade,
        FatherName = x.FatherName,
        FirstName = x.LegName?.FirstName, // sanity check incase LegName is null
        LastName = x.LegName?.LastName, // ...
        School = schools.ContainsKey(x.SchoolId ?? string.Empty) ? schools[x.SchoolId] : null,
        Teacher = teachers.ContainsKey(x.TeacherId ?? string.Empty) ? teachers[x.TeacherId] : null
    });
    csv.WriteRecords(normalizedData);
}

private static string GenerateStringCSVData(Dictionary<string, string> schools,
    Dictionary<string, string> teachers, Student[] students)
{
    using(var ms = new MemoryStream())
    {
        using(var sr = new StreamWriter(ms, leaveOpen: true))
        using (var csv = new CsvHelper.CsvWriter(sr,
            new CsvConfiguration(CultureInfo.InvariantCulture)
        {
            Delimiter = ",", // change this to "\t" if you want to use tabs
            Encoding = Encoding.UTF8
        }))
        {
            GenerateCSVData(csv, schools, teachers, students);
        }
        ms.Position = 0;
        return Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length);
    }
}

private static int Main(string[] args)
{
    var teachers = new Dictionary<string, string>
    {
        { "j123", "Jimmy Carter" },
        { "r334", "Ronald Reagan" },
        { "g477", "George Bush" }
    };
    var schools = new Dictionary<string, string>
    {
        { "s123", "Jimmy Carter University" },
        { "s334", "Ronald Reagan University" },
        { "s477", "George Bush University" }
    };

    var students = new Student[]
    {
        new Student
        {
            FatherName = "Bob Jimmy",
            SchoolId = "s477",
            Grade = "5",
            LegName = new Name{ FirstName = "Apple", LastName = "Jimmy" },
            TeacherId = "r334"
        },
        new Student
        {
            FatherName = "Jim Bobby",
            SchoolId = null, // intentional
            Grade = "", // intentional
            LegName = null, // intentional
            TeacherId = "invalid id" // intentional
        },
        new Student
        {
            FatherName = "Mike Michael",
            SchoolId = "s123",
            Grade = "12",
            LegName = new Name{ FirstName = "Peach", LastName = "Michael" },
            TeacherId = "g477"
        },
    };

    var stringData = GenerateStringCSVData(schools, teachers, students);

    return 0;
}
因此,您可以看到,其中一个学生有无效数据,但它通过放置空白数据而不是崩溃或抛出异常来恢复正常


现在我还没有看到您的原始数据,因此您可能需要对其进行更多调整,以涵盖所有边缘情况,但当使用CsvHelper作为您的作者时,调整将更容易。

感谢您的时间!因此,广义上讲,您的建议是处理每一列中的每一种可能情况,直到不存在异常为止好消息CsvHelper@Aferrercrafter--是的,您希望在不停止的情况下处理所有数据。您已经知道数据可能/正在丢失,但如果是这种情况,则可以这样做。您可以不设置空白数据,而是将“”在这些点上,使用此CSV的任何人都知道这是故意的,因为数据不在原始集中。是的,空格是一条业务规则。还有列的顺序,我的问题开始了,因为最后几列中有几个是hacoded值。因此,对于我处理它时遇到的每一个错误,我都有数百行h空列,包括列​​这应该总是存在的,因为它们是harcoded值
Grade,FirstName,LastName,School,Teacher,FatherName
5,Apple,Jimmy,George Bush University,Ronald Reagan,Bob Jimmy
,,,,,Jim Bobby
12,Peach,Michael,Jimmy Carter University,George Bush,Mike Michael