You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用FastMember创建含子对象属性的IDataReader以实现SQLBulkCopy

解决FastMember ObjectReader包含嵌套对象属性的问题

这个场景我之前处理过,FastMember的ObjectReader默认只会读取顶层对象的属性,不会自动展开嵌套的子对象。不过有两种实用的办法能帮你把子对象的属性也纳入到IDataReader中:

方法一:显式指定嵌套属性路径

最直接的方式就是在创建ObjectReader时,用点语法明确写出嵌套对象的属性路径。如果数据库表的列名和嵌套属性路径不一致,还可以用别名来映射。

举个例子,假设你的记录类是这样的:

public class CustomerRecord
{
    public int Id { get; set; }
    public string Name { get; set; }
    public AddressInfo Address { get; set; }
}

public class AddressInfo
{
    public string Street { get; set; }
    public string City { get; set; }
    public string ZipCode { get; set; }
}

情况1:数据库列名和属性路径一致

直接在ObjectReader.Create的参数里列出所有需要的属性:

using (var reader = ObjectReader.Create(customer.Records, 
    "Id", "Name", "Address.Street", "Address.City", "Address.ZipCode"))
{
    DataAccess.BulkInsert(serverName, databaseName, tableName, reader);
}

情况2:数据库列名和属性路径不一致

用键值对来指定属性路径和对应的列别名:

using (var reader = ObjectReader.Create(customer.Records, 
    // 顶层属性直接写名称
    "Id", "Name",
    // 嵌套属性用KeyValuePair指定路径和别名
    new KeyValuePair<string, string>("Address.Street", "Street"),
    new KeyValuePair<string, string>("Address.City", "City"),
    new KeyValuePair<string, string>("Address.ZipCode", "ZipCode")))
{
    DataAccess.BulkInsert(serverName, databaseName, tableName, reader);
}

方法二:动态生成所有扁平化属性路径

如果嵌套对象的属性很多,不想手动一个个列出来,可以写个辅助方法,通过反射递归收集所有顶层和嵌套的属性路径,再传给ObjectReader。

辅助方法代码

using System.Reflection;

private static IEnumerable<string> GetFlatPropertyPaths(Type targetType)
{
    // 遍历所有公共实例属性
    foreach (var property in targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        // 值类型或string直接返回属性名
        if (property.PropertyType.IsValueType || property.PropertyType == typeof(string))
        {
            yield return property.Name;
        }
        // 引用类型(排除string)则递归遍历子属性
        else
        {
            foreach (var nestedPath in GetFlatPropertyPaths(property.PropertyType))
            {
                yield return $"{property.Name}.{nestedPath}";
            }
        }
    }
}

使用方式

// 获取CustomerRecord所有扁平化的属性路径
var allPropertyPaths = GetFlatPropertyPaths(typeof(CustomerRecord)).ToArray();

using (var reader = ObjectReader.Create(customer.Records, allPropertyPaths))
{
    DataAccess.BulkInsert(serverName, databaseName, tableName, reader);
}

注意事项

  • FastMember会自动处理嵌套对象为null的情况,此时对应的属性值会返回DBNull,不会抛出空引用异常。
  • 如果有多层嵌套(比如Address.Country.Name),点语法同样适用,辅助方法也会自动递归收集。
  • 如果需要排除某些属性,在GetFlatPropertyPaths方法里添加过滤逻辑即可(比如跳过特定名称的属性)。

内容的提问来源于stack exchange,提问作者Muds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:48:14