CsvHelper 忽略复杂类型

CsvHelper Ignore Complex Types

我正在尝试将 CSV 文件中的测试数据加载到可以加载到内存中 EF 核心数据库上下文中的记录中。

我有一个简化后的实体:

public class Project
{
   public int { get; set; }
   public Owner? Owner { get; set; } = null;
}

一个class地图:

public class ProjectsClassMap : CsvHelper.Configuration.ClassMap<Projects>
{
     public ProjectsClassMap()
     {
        AutoMap(CultureInfo.CurrentCulture);
        Map(m => m.Owner).Ignore();

    }
}

然后像这样加载数据的函数:

private void LoadTestData<T>(string fileName, InMemoryEFCoreDbContext db, Type? classMap = null)
            where T : class
        {
            var data = GetTestData(fileName);
            var readerConfig = new CsvConfiguration(CultureInfo.CurrentCulture) {
                Delimiter = ",",
                PrepareHeaderForMatch = (r, c) => r.Replace(" ", string.Empty).ToLower(),
                MissingFieldFound = (string[] values, int index, ReadingContext context) => { },
                ReadingExceptionOccurred = (ex) => false,
                HeaderValidated = (isValid, headerNames, headerNameIndex, context) => { },
                HasHeaderRecord = true,
                UseNewObjectForNullReferenceMembers = true,
            };
            if(classMap != null)
            {
                readerConfig.RegisterClassMap(classMap);
                readerConfig.IgnoreReferences = true;
            }
            
            using (var sReader = new StringReader(data))
            using (var csvReader = new CsvHelper.CsvReader(sReader, readerConfig))
            {
                var records = csvReader.GetRecords<T>().ToList();
                db.Set<T>().AddRange(records);
                db.SaveChanges();
            }
        }

问题是 Owner 设置为新值而不是默认值 null,这会在尝试保存到 DbContext 时导致验证错误。如何将复杂引用类型保留为 null 而不是 new?

试试这个

public class ProjectsClassMap : CsvHelper.Configuration.ClassMap<Project>
{
    public ProjectsClassMap()
    {
        var config = new CsvConfiguration(CultureInfo.CurrentCulture)
        {
            IgnoreReferences = true
        };
        AutoMap(config);
    }
}

来自@JoshClose 的更新

The issue here is that AutoMap will set up all properties down the tree and ignoring that property doesn't remove all the properties on Owner.

使用不带 ProjectsClassMap[Ignore] 属性,AutoMap 将正确设置它。

public class Project
{
   public int { get; set; }
   [Ignore]
   public Owner? Owner { get; set; } = null;
}

或者,如果您需要使用 class 地图,则必须手动删除引用。

public class ProjectsClassMap : CsvHelper.Configuration.ClassMap<Project>
{
    public ProjectsClassMap()
    {   
        AutoMap(CultureInfo.CurrentCulture);
        ReferenceMaps.Remove(ReferenceMaps.Find<Project>(m => m.Owner));
    }
}