如何通过Data驱动mapper class

How to drive mapper class through Data

我正在尝试接受客户端 CSV 文件,将其映射为标准格式,并生成标准输出。除了,每个客户可以不同地命名 headers 并且不能保证顺序位置。

我已经为标准格式创建了 Class。我什至为它创建了一个有效的映射器。我只想将映射器放在数据库中,这样我就可以为映射添加行,而不是每次客户端更改其源文件时都重建和部署此代码。

static void Main()
        {
            using (var reader = new StreamReader("filepath\filename.csv"))
            using (var writer = new StreamWriter("filepath\Output filename.csv"))
            using (var csvIn = new CsvReader(reader))
            {
                csvIn.Configuration.RegisterClassMap<CsvMap>();
                csvIn.Configuration.PrepareHeaderForMatch = (string header, int index) => header.ToUpper();
                var records = csvIn.GetRecords<CsvClass>();
                using (var csvOut = new CsvWriter(writer))
                {
                    csvOut.WriteRecords(records);
                }
            }

        }

public class CsvClass
        {
            [Optional]
            public Guid CompanyID{ get; set; }
            [Optional]
            public string RecordID{ get; set; }
        }
        public sealed class CsvMap : ClassMap<CsvClass>
        {
            public CsvMap()
            {
                Map(m => m.CompanyID).Name("OrganizationID").Optional();
                Map(m => m.CompanyID).Name("CompanyID").Optional();
                Map(m => m.RecordID).Name("RecordID").Optional();
            }
        }

我是一名数据库开发人员,不擅长 C#,需要一个指向我应该使用什么来制作它的指针,以便可以通过数据库或 json 完成这些映射并构建它们易于维护。

{"target_field" : "CompanyID"
 "source_field" : "OrganizationID"},
{"target_field" : "CompanyID"
 "source_field" : "CompanyID"},
{"target_field" : "RecordID"
 "source_field" : "RecordID"},

感谢您的帮助

这是我使用的,这样我就可以让我的用户输入他们使用的标题的名称并将其保存在数据库中 table。

CsvMapping class 存储 header 名称和 class 的 属性 名称。

public class CsvMapping 
{
    public string CsvHeaderName { get; set; }
    public string PropertyName { get; set; }
}

然后我使用一个辅助扩展,它获取 CsvMapping 的列表并将它们添加到 ClassMap

public static class CsvHelperExtensions
{
    public static void Map<T>(this ClassMap<T> classMap, IEnumerable<CsvMapping> csvMappings)
    {
        foreach (var mapping in csvMappings)
        {
            var property = typeof(T).GetProperty(mapping.PropertyName);

            if (property == null)
            {
                throw new ArgumentException($"Class {typeof(T).Name} does not have a property named {mapping.PropertyName}");
            }

            if (mapping.CsvHeaderName != null)
            {
                classMap.Map(typeof(T), property).Name(mapping.CsvHeaderName);
            }
        }
    }
}

之后就可以这样使用了。

public static void Main(string[] args)
{
    using (MemoryStream stream = new MemoryStream())
    using (StreamWriter writer = new StreamWriter(stream))
    using (StreamReader reader = new StreamReader(stream))
    using (CsvReader csv = new CsvReader(reader))
    {
        writer.WriteLine("OrganizationID,RecordID");
        writer.WriteLine("0CEB1F84-4EA6-4C6D-B758-93BFCDF2B8DE,Record1");
        writer.Flush();
        stream.Position = 0;

        var mappings = new List<CsvMapping>
        {
            new CsvMapping { CsvHeaderName = "OrganizationID", PropertyName = "CompanyID" },
            new CsvMapping { CsvHeaderName = "RecordID", PropertyName = "RecordID" }
        };

        var csvMap = new CsvMap();

        csvMap.Map(mappings);

        csv.Configuration.RegisterClassMap(csvMap);

        var records = csv.GetRecords<CsvClass>().ToList();    
    }
}

public sealed class CsvMap : ClassMap<CsvClass>
{
    public CsvMap()
    {
        Map(m => m.CompanyID).Optional();
        Map(m => m.RecordID).Optional();
    }
}