CsvHelper动态列映射:如何用字符串指定类属性实现列名映射
CsvHelper动态列映射实现方案
该动态映射功能完全可以实现,你之前的写法不生效是因为CsvHelper的Map方法需要接收属性访问表达式树,而非直接传入PropertyInfo对象,正确实现方式如下:
核心实现逻辑
通过反射构造CsvHelper要求的属性访问表达式树,再调用官方的映射方法完成绑定,你可以直接复用下面封装好的动态映射类:
using CsvHelper.Configuration; using System.Linq.Expressions; using System.Reflection; /// <summary> /// 支持动态配置的CsvHelper映射类 /// </summary> /// <typeparam name="T">业务模型类</typeparam> public class DynamicClassMap<T> : ClassMap<T> { /// <summary> /// 绑定模型属性与CSV列名 /// </summary> /// <param name="modelPropertyName">业务模型的属性名</param> /// <param name="csvColumnName">CSV文件对应的列名</param> /// <exception cref="ArgumentException">属性不存在时抛出异常</exception> public void MapProperty(string modelPropertyName, string csvColumnName) { // 校验属性是否存在 PropertyInfo prop = typeof(T).GetProperty(modelPropertyName); if (prop == null) { throw new ArgumentException($"类 {typeof(T).Name} 中不存在属性 {modelPropertyName}", nameof(modelPropertyName)); } // 构造属性访问表达式树:m => m.PropertyName ParameterExpression parameter = Expression.Parameter(typeof(T), "m"); MemberExpression propertyAccess = Expression.Property(parameter, prop); LambdaExpression accessLambda = Expression.Lambda(propertyAccess, parameter); // 反射调用CsvHelper的Map方法 var mapMethod = typeof(ClassMap<T>) .GetMethods() .First(m => m.Name == "Map" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(LambdaExpression)); var memberMap = mapMethod.Invoke(this, new object[] { accessLambda }); // 绑定CSV列名 var nameMethod = memberMap.GetType().GetMethod("Name", new[] { typeof(string) }); nameMethod.Invoke(memberMap, new object[] { csvColumnName }); } }
使用示例
1. 定义业务模型
public class MyClassModel { public int Col1 { get; set; } public string Col2 { get; set; } }
2. 加载数据库映射关系完成配置
// 从数据库读取映射关系,示例结构为(模型属性名,CSV列名) var dbMappings = new List<(string ModelProp, string CsvColumn)> { ("Col1", "ColumnA"), ("Col2", "ColumnB") }; // 初始化动态映射 var dynamicMap = new DynamicClassMap<MyClassModel>(); foreach (var mapping in dbMappings) { dynamicMap.MapProperty(mapping.ModelProp, mapping.CsvColumn); } // 注册映射到CsvHelper配置 var csvConfig = new CsvHelper.Configuration.CsvConfiguration(System.Globalization.CultureInfo.InvariantCulture); csvConfig.RegisterClassMap(dynamicMap);
之后你就可以用这个csvConfig正常初始化CsvReader/CsvWriter实现读写,完全兼容CsvHelper的所有原生功能。
内容的提问来源于stack exchange,提问作者Franky
相关产品推荐
相关产品推荐

