EF 6 .NET Core中如何将可枚举匿名类型转换为指定Customer模型?
问题原因
你用到的OfType和Cast方法失效的核心逻辑是:查询返回的是运行时生成的匿名类实例,和你定义的Customer实体类没有任何继承、隐式/显式转换关系,OfType会过滤所有类型不匹配的元素所以返回空列表,Cast强制转换时类型不兼容自然会抛出异常。
可行解决方案
方案1:查询阶段直接投影为Customer类(最推荐)
不需要先查匿名类再二次转换,直接在EF查询阶段就投影为Customer实例,EF会自动生成只查询你需要的字段的SQL,性能和查匿名类完全一致,省去后续转换步骤:
List<Customer> list1 = (from r in _context.Customers select new Customer() { IdNo = r.IdNo, Status = r.Status, RenterName = r.RenterName, // 未手动赋值的字段会自动保持对应类型的默认值,和你手写foreach赋值效果完全一致 }).ToList();
方案2:用AutoMapper自动映射(适合字段多、查询逻辑无法修改的场景)
如果已经拿到了匿名类的结果集,不想手写大量字段赋值代码,可以用AutoMapper做自动属性映射,只要属性名和类型完全匹配,不需要手动写映射规则:
- 先安装AutoMapper NuGet包
- 映射代码示例:
// 全局只需要配置一次即可,比如放在Program.cs启动逻辑中 var mapperConfig = new MapperConfiguration(cfg => {}); var mapper = mapperConfig.CreateMapper(); // 直接转换已有的匿名类列表 List<Customer> list1 = result.Select(mapper.Map<Customer>).ToList();
方案3:手写反射通用映射(不想引入第三方库时使用)
如果不想引入外部依赖,可以自己写一个通用反射扩展方法完成属性映射,适合字段量不大的场景:
// 定义通用扩展方法 public static class MapExtension { public static T MapTo<T>(this object sourceObj) where T : new() { var target = new T(); var sourceProps = sourceObj.GetType().GetProperties().ToDictionary(p => p.Name); var targetProps = typeof(T).GetProperties(); foreach (var targetProp in targetProps) { if (!targetProp.CanWrite) continue; if (sourceProps.TryGetValue(targetProp.Name, out var sourceProp) && sourceProp.PropertyType == targetProp.PropertyType) { targetProp.SetValue(target, sourceProp.GetValue(sourceObj)); } } return target; } } // 使用扩展方法转换 List<Customer> list1 = result.Select(x => x.MapTo<Customer>()).ToList();
内容的提问来源于stack exchange,提问作者Ben Junior
相关产品推荐
相关产品推荐

