首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用CSVWriter强制字符串长度

使用CSVWriter强制字符串长度
EN

Stack Overflow用户
提问于 2020-01-05 20:43:23
回答 1查看 928关注 0票数 1

我目前正在进行一个项目,将SaaS工具(通过API)中的JSON数据提取到一个SQL数据库中。最终,这些数据将用于报告目的(作为Tableau中的数据源)。

以下是整个流程流程:

将原始JSON数据(使用RestSharp).

  • Convert每条记录到POCO (使用JSON.NET + json2csharp生成POCO类))。

注意:对每个对象重复这些步骤。大约有10个对象,每个对象在10到150个字段(列)之间的任何位置。所有的POCO属性都是字符串(这很糟糕吗?)

问题:我得到截断错误,因为我不确定在每一列上定义/强制执行大小限制的最佳方法。有些列是自由文本段落字段,因此每个列的“最大大小”可能会发生变化,这将导致截断错误。在web端没有保证/定义数据的特定架构的文档。

如何在步骤5之前为每一列定义模式/最大长度,以避免出现截断错误?

我知道我可以在POCO定义中定义每个字段的最大长度:但是我有10个POCOs,有数百个字段。做这件事最好的方法是什么?

EN

回答 1

Stack Overflow用户

发布于 2020-01-07 15:04:35

这样做的一种方法是查询数据库以查找文本列的最大长度。下面使用Dapper查询Server数据库,但是您应该能够修改该示例以与其他or或数据库提供程序一起工作。如果文本长度大于属性的最大长度,则此示例将引发异常,但您可以将其修改为截断字符串。

代码语言:javascript
复制
public class Program
{
    public static void Main(string[] args)
    {
        var connection = "Data Source=ServerName;Initial Catalog=MyDatabase;Integrated Security=true";
        var sql = @"
SELECT 
  COLUMN_NAME as ColumnName, 
  CHARACTER_MAXIMUM_LENGTH as CharacterMaximumLength 
FROM 
  INFORMATION_SCHEMA.COLUMNS 
WHERE 
  TABLE_NAME = @TableName AND CHARACTER_MAXIMUM_LENGTH IS NOT NULL";

        List<MaxLength> maxLengths;

        using (var db = new SqlConnection(connection))
        {
            maxLengths = db.Query<MaxLength>(sql, new { TableName = "MyClassExample" }).AsList();
        }

        var records = new List<MyClassExample>
        {
            new MyClassExample {Id = 1, PropertyName = "First"},
            new MyClassExample {Id = 2, PropertyName = "Second is certainly longer than the 50 characters maximum length."}
        };

        using (var csv = new CsvWriter(Console.Out))
        {
            var classMap = new DefaultClassMap<MyClassExample>();
            classMap.AutoMap(); 
            classMap.RegisterMaxLengths(maxLengths);
            csv.Configuration.RegisterClassMap(classMap);

            csv.WriteRecords(records);
        }

        Console.ReadLine();
    }
}

public class MyClassExample
{
    public int Id { get; set; }
    public string PropertyName { get; set; }
}

public class MaxLengthConverter : StringConverter
{
    private readonly int _maxLength = 0;
    public MaxLengthConverter(int maxLength)
    {
        _maxLength = maxLength;
    }

    public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        if (value is string text)
            if (text.Length > _maxLength)
            {
                var message =   $"The text with length {text.Length} exceeds the maximum allowed length of {_maxLength}.\r\n" +
                                $"    Text: '{text}'\r\n" +
                                $"    Property: {memberMapData.Member?.Name}\r\n" +
                                $"    TypeConverter: '{memberMapData.TypeConverter?.GetType().FullName}'";
                throw new TypeConverterException(this, memberMapData, value, row.Context, message);
            }

        return base.ConvertToString(value, row, memberMapData);
    }
}

public class MaxLength
{
    public string ColumnName { get; set; }
    public int CharacterMaximumLength { get; set; }
}

public static class CsvHelpExtensions
{
    public static void RegisterMaxLengths<T>(this ClassMap<T> map, IEnumerable<MaxLength> maxLengths)
    {
        foreach (var property in typeof(T).GetProperties())
        {
            var maxLength = maxLengths.Where(m => m.ColumnName.ToLower() == property.Name.ToLower()).FirstOrDefault();
            if (maxLength != null)
                map.Map(typeof(T), property, true).TypeConverter(new MaxLengthConverter(maxLength.CharacterMaximumLength));
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59604023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档