简体   繁体   English

从动态集合创建地图不再有效:无法将 System.String 类型的 object 转换为 System.Object)

[英]Create maps from dynamic collection no longer works: Unable to cast object of type System.String to System.Object)

We are porting legacy code to dotnet standard and are facing an issue which [I believe] wasn't present in CsvHelper 2.5.0 net451.我们正在将遗留代码移植到 dotnet 标准,并面临 [我相信] CsvHelper 2.5.0 net451 中不存在的问题。

The issue appears to be that CsvReader can't manage to resolve the correct ReturnType of the underlying properties in the mappings and is trying to map them all to System.Object问题似乎是 CsvReader 无法解决映射中基础属性的正确 ReturnType 并尝试将它们全部 map 到 System.Object

I have managed to reproduce it with a unit test in your solution:我已经设法在您的解决方案中通过单元测试来重现它:

[TestMethod]
public void CanCreateMapsFromDynamicList()
{
    var data = new List<string[]>
    {
        new[] { "Col1", "Col2" },
        new[] { "1", "one" },
        new[] { "2", "two" }
    };

    var queue = new Queue<string[]>(data);
    var parserMock = new ParserMock(queue);

    var csvReader = new CsvReader(parserMock);
    csvReader.Configuration.RegisterClassMap<SomeTypeClassMap>();

    var records = csvReader.GetRecords<SomeType>().ToList();

    Assert.IsNotNull(records);
    Assert.AreEqual(2, records.Count);

}

public class SomeTypeClassMap : ClassMap<SomeType>
{
    public SomeTypeClassMap()
    {
        Map(x => x.Id).Ignore();
        var t = new SomeType();

        foreach (var mapping in t.Mappings)
        {
            Map(mapping);
        }
    }
}

public class SomeType
{
    public int Id { get; set; }
    public string Col1 { get; set; }
    public string Col2 { get; set; }

    public IEnumerable<Expression<Func<SomeType, dynamic>>> Mappings =>
        new List<Expression<Func<SomeType, dynamic>>> {i => i.Col1, i => i.Col2};
}

Error reported:报错:

Test method CsvHelper.Tests.CsvReaderMappingTestsRuslan.CanCreateMapsFromDynamicList threw exception: System.InvalidCastException: Unable to cast object of type 'CsvHelper.Configuration.MemberMap2[CsvHelper.Tests.CsvReaderMappingTestsRuslan+SomeType,System.String]' to type 'CsvHelper.Configuration.MemberMap2[CsvHelper.Tests.CsvReaderMappingTestsRuslan+SomeType,System.Object]'.测试方法 CsvHelper.Tests.CsvReaderMappingTestsRuslan.CanCreateMapsFromDynamicList 抛出异常:System.InvalidCastException:无法将“CsvHelper.Configuration.MemberMap2[CsvHelper.Tests.CsvReaderMappingTestsRuslan+SomevMap2HelperMappingTestsRuslan+SomevType2Helper. [CsvHelper.Tests.CsvReaderMappingTestsRuslan+SomeType,System.Object]'。

PS I've tried changing "Mappings" property to static and getting the same result. PS我尝试将“映射”属性更改为 static 并获得相同的结果。

resolved it by adding this overload method:通过添加此重载方法解决了它:

    public virtual MemberMap Map<T>( Expression<Func<T, object>> expression, bool useExistingMap = true )
    {
        var stack = ReflectionHelper.GetMembers(expression);
        if (stack.Count == 0)
        {
            throw new InvalidOperationException("No members were found in expression '{expression}'.");
        }

        ClassMap currentClassMap = this;
        MemberInfo member;

        if (stack.Count > 1)
        {
            // We need to add a reference map for every sub member.
            while (stack.Count > 1)
            {
                member = stack.Pop();
                Type mapType;
                var property = member as PropertyInfo;
                var field = member as FieldInfo;
                if (property != null)
                {
                    mapType = typeof(DefaultClassMap<>).MakeGenericType(property.PropertyType);
                }
                else if (field != null)
                {
                    mapType = typeof(DefaultClassMap<>).MakeGenericType(field.FieldType);
                }
                else
                {
                    throw new InvalidOperationException("The given expression was not a property or a field.");
                }

                var referenceMap = currentClassMap.References(mapType, member);
                currentClassMap = referenceMap.Data.Mapping;
            }
        }

        // Add the member map to the last reference map.
        member = stack.Pop();

        return currentClassMap.Map( typeof(TClass), member, useExistingMap );
    }

PR raised https://github.com/JoshClose/CsvHelper/pull/1505 PR 提出https://github.com/JoshClose/CsvHelper/pull/1505

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法将类型“ System.String”强制转换为类型“ System.Object” - Unable to cast the type 'System.String' to type 'System.Object' 多维数组转换运行时错误---&gt;无法将类型为&#39;System.Object [,]&#39;的对象转换为&#39;System.String类型 - Multidimensional Array Casting Runtime Error ---> unable to cast object of type 'System.Object[,]' to type 'System.String 无法将类型为&#39;System.Object []&#39;的对象强制转换为&#39;System.String []&#39; - Unable to cast object of type 'System.Object[]' to type 'System.String[]' 无法将类型“ System.String”强制转换为类型“ System.Object”。 LINQ to Entities仅支持转换实体数据模型原语类型 - Unable to cast the type 'System.String' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types 无法将“System.String”类型的对象转换为“System.Collections.Generic.List`1[System.String]”类型 - Unable to cast object of type 'System.String' to type 'System.Collections.Generic.List`1[System.String]' 无法将“ System.Object []”转换为类型“ System.String []” - Cannot convert 'System.Object[]' to the type 'System.String[]' Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]' - Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]' 无法将“OpenQA.Selenium.Remote.RemoteWebElement”类型的对象强制转换为“System.Collections.Generic.Di ctionary”2 [System.String,System.Object] - Unable to cast object of type 'OpenQA.Selenium.Remote.RemoteWebElement' to type 'System.Collections.Generic.Di ctionary`2[System.String,System.Object] 无法将类型类的对象强制转换为“ System.String”类型 - Unable to cast object of type class to type 'System.String' 无法将“DapperRow”类型的对象转换为“System.String”类型 - Unable to cast object of type 'DapperRow' to type 'System.String'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM