| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Data;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace PTMedicalInsurance.CustomExtensions
- {
- public class FieldMapping<T>
- {
- // 缓存字典(避免重复转换 DataTable)
- private static readonly ConcurrentDictionary<string, Dictionary<string, string>> _cache
- = new ConcurrentDictionary<string, Dictionary<string, string>>();
- public Func<T, string> SourceValueSelector { get; }
- public Dictionary<string, string> LookupMap { get; }
- public Action<T, string> ValueAssigner { get; }
- public FieldMapping(
- Func<T, string> sourceValueSelector,
- Dictionary<string, string> lookupMap,
- Action<T, string> valueAssigner)
- {
- SourceValueSelector = sourceValueSelector;
- LookupMap = lookupMap;
- ValueAssigner = valueAssigner;
- }
- // 用于创建“空映射”——不进行任何替换
- private static readonly Dictionary<string, string> _emptyMap = new Dictionary<string, string>();
- /// <summary>
- /// 安全创建字段映射:任何错误都静默处理,不抛异常
- /// </summary>
- public static FieldMapping<T> For(
- Func<T, string> sourceValueSelector,
- DataTable sourceTable,
- string codeColumn,
- string nameColumn,
- Action<T, string> valueAssigner)
- {
- // ✅ 任何环节出错都返回“空映射”,不抛异常
- try
- {
- // 1. 参数为空?→ 跳过
- if (sourceValueSelector == null || sourceTable == null ||
- string.IsNullOrEmpty(codeColumn) || string.IsNullOrEmpty(nameColumn) ||
- valueAssigner == null)
- {
- return new FieldMapping<T>(sourceValueSelector, _emptyMap, valueAssigner);
- }
- // 2. 列不存在?→ 跳过
- if (!sourceTable.Columns.Contains(codeColumn) || !sourceTable.Columns.Contains(nameColumn))
- {
- return new FieldMapping<T>(sourceValueSelector, _emptyMap, valueAssigner);
- }
- // 3. 表为空?→ 跳过
- if (sourceTable.Rows.Count == 0)
- {
- return new FieldMapping<T>(sourceValueSelector, _emptyMap, valueAssigner);
- }
- // 4. 提取字典(使用缓存)
- string key = $"{sourceTable.TableName ?? "Table"}_{codeColumn}_{nameColumn}";
- var map = _cache.GetOrAdd(key, _ =>
- {
- try
- {
- return sourceTable.AsEnumerable()
- .Where(row => !row.IsNull(codeColumn))
- .ToDictionary(
- row => row.Field<string>(codeColumn),
- row => row.Field<string>(nameColumn) ?? "",
- StringComparer.OrdinalIgnoreCase);
- }
- catch
- {
- // 字典构建失败 → 返回空字典
- return _emptyMap;
- }
- });
- return new FieldMapping<T>(sourceValueSelector, map, valueAssigner);
- }
- catch
- {
- // ✅ 所有异常都被捕获,返回空映射
- return new FieldMapping<T>(sourceValueSelector, _emptyMap, valueAssigner);
- }
- }
-
- }
- public static class ListExtensions
- {
- /// <summary>
- /// 将 List 中某字段的值通过映射表转换为新值,并返回新 List(不修改原对象)
- /// </summary>
- /// <typeparam name="T">列表元素类型</typeparam>
- /// <param name="list">源列表</param>
- /// <param name="sourceFieldSelector">要转换的字段(如 x => x.Status)</param>
- /// <param name="mapTable">映射表(含 Code 和 Description 列)</param>
- /// <param name="keyColumn">映射表中键列名(如 "Code")</param>
- /// <param name="valueColumn">映射表中值列名(如 "Description")</param>
- /// <param name="converter">转换后设置值的委托(如 x => x.StatusDesc = value)</param>
- /// <returns>返回新 List,字段已转换</returns>
- public static List<T> MapField<T>(
- this List<T> list,
- Func<T, object> sourceFieldSelector,
- DataTable mapTable,
- string keyColumn,
- string valueColumn,
- Action<T, string> converter)
- {
- if ((mapTable == null) || mapTable.Rows.Count == 0)
- {
-
- }
- // 构建映射字典
- var dict = mapTable.AsEnumerable()
- .ToDictionary(
- r => r.Field<object>(keyColumn),
- r => r.Field<string>(valueColumn)
- );
- foreach (var item in list)
- {
- var key = sourceFieldSelector(item);
- var value = dict.TryGetValue(key, out string mapped) ? mapped : key.ToString();
- converter(item, value);
- }
- return list; // 返回原列表(已修改),也可 new List 返回副本
- }
- public static List<T> MapFields<T>(this List<T> list, params FieldMapping<T>[] mappings)
- {
- // 空列表或 null → 直接返回
- if (list == null || list.Count == 0 || mappings == null || mappings.Length == 0)
- return list;
- foreach (var item in list)
- {
- foreach (var mapping in mappings)
- {
- try
- {
- string code = mapping.SourceValueSelector(item);
- if (string.IsNullOrEmpty(code))
- continue;
- if (mapping.LookupMap.TryGetValue(code, out string desc))
- {
- mapping.ValueAssigner(item, desc);
- }
- }
- catch
- {
- // 单个对象处理失败,不影响其他对象
- continue;
- }
- }
- }
- return list;
- }
- }
- }
|