C#中将匿名类型转列表时出现TargetInvocationException错误求助
首先要明确:System.Reflection.TargetInvocationException通常是一个包装异常,它本身不是真正的错误原因——你需要查看这个异常的InnerException属性,才能找到导致崩溃的具体异常(比如类型不匹配、空引用、无效转换等)。
接下来结合你的代码,我们来逐一排查可能的问题:
1. 确认castapprove已正确初始化
如果castapprove没有被实例化为List<muapprovelist>,直接调用Add方法会抛出NullReferenceException,而这个异常可能被包装成TargetInvocationException。
检查你的代码开头是否有类似这样的初始化:
var castapprove = new List<muapprovelist>();
2. 检查类型匹配问题
匿名类型的属性类型必须和muapprovelist类的对应属性完全一致,否则赋值时会抛出类型转换异常,进而被包装成TargetInvocationException。
比如:
- 如果
a.ID是int类型,但muapprovelist.Id是string类型,赋值时会失败; - 如果
b.MU_Identifier是Guid,但模型里的MU_Identifier是string且没有显式转换,也会出错; - 如果
Status是可空类型(比如int?),但模型里的Status是不可空int,而查询结果中存在null值,就会抛出InvalidCastException。
你可以先临时打印类型信息做对比:
// 在foreach前添加,查看类型是否匹配 var sampleItem = all.FirstOrDefault(); if(sampleItem != null) { Console.WriteLine($"匿名类型ID类型: {sampleItem.ID.GetType()},模型Id类型: {typeof(muapprovelist).GetProperty("Id").PropertyType}"); }
3. 排查LINQ查询的数据源问题
如果Fcticuclist或crlist是EF等ORM的查询结果(即IQueryable),那么foreach时才会真正执行数据库查询。这时候如果数据库中的数据有问题(比如关联字段为null、字段值超出类型范围),也会抛出异常并被包装。
你可以先把查询结果转为内存集合,提前触发查询,看是否直接抛出具体异常:
var all = (from a in Fcticuclist join b in crlist on a.Ref_CID equals b.C_ID select new { b.MU_Identifier, a.Status,a.ID }).ToList();
4. 简化代码,避免手动foreach
其实你可以直接用LINQ的Select和ToList方法完成转换,不需要手动foreach,这样代码更简洁,也更容易定位问题:
var all = from a in Fcticuclist join b in crlist on a.Ref_CID equals b.C_ID select new { b.MU_Identifier, a.Status,a.ID }; // 直接转换为List<muapprovelist> castapprove = all.Select(item => new muapprovelist { Id = item.ID, MU_Identifier = item.MU_Identifier, Status = item.Status }).ToList();
最后再强调一次:一定要先查看InnerException的详细信息,这是解决这类包装异常最关键的一步。
内容的提问来源于stack exchange,提问作者Sam King

