我目前正在进行一个项目,将SaaS工具(通过API)中的JSON数据提取到一个SQL数据库中。最终,这些数据将用于报告目的(作为Tableau中的数据源)。
以下是整个流程流程:
将原始JSON数据(使用RestSharp).
JSON.NET + json2csharp生成POCO类))。注意:对每个对象重复这些步骤。大约有10个对象,每个对象在10到150个字段(列)之间的任何位置。所有的POCO属性都是字符串(这很糟糕吗?)
问题:我得到截断错误,因为我不确定在每一列上定义/强制执行大小限制的最佳方法。有些列是自由文本段落字段,因此每个列的“最大大小”可能会发生变化,这将导致截断错误。在web端没有保证/定义数据的特定架构的文档。
如何在步骤5之前为每一列定义模式/最大长度,以避免出现截断错误?
我知道我可以在POCO定义中定义每个字段的最大长度:但是我有10个POCOs,有数百个字段。做这件事最好的方法是什么?
发布于 2020-01-07 15:04:35
这样做的一种方法是查询数据库以查找文本列的最大长度。下面使用Dapper查询Server数据库,但是您应该能够修改该示例以与其他or或数据库提供程序一起工作。如果文本长度大于属性的最大长度,则此示例将引发异常,但您可以将其修改为截断字符串。
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));
}
}
}https://stackoverflow.com/questions/59604023
复制相似问题