ASP.NET MVC配合EF6关联两张表出现类型异常问题求助
错误原因
你在Join方法中使用了匿名类投影(p, c) => new { Amount=c.Amount },最终查询返回的是匿名类型集合,但视图声明的接收模型类型为IEnumerable<TransportRegistration.UserToTransport>,二者类型不匹配因此触发报错。去掉Join语句时查询直接返回UserToTransport类型的集合,和视图要求一致,因此运行正常。
解决方案
根据你的实际开发需求选择对应方案即可:
方案1:仅筛选存在保险记录的UserToTransport
如果你不需要在视图中显示保险金额,只是要过滤出有对应保险记录的关联数据,直接返回Join后的UserToTransport对象即可,无需额外投影:
var userToTransports = db.UserToTransports .Include(u => u.Transport) .Include(u => u.User) .Include(u => u.User1) .Where(u => u.User.Login.Equals(user)) .Join( db.Insurences, p => p.Transport_id, c => c.Transport_id, (p, c) => p // 直接返回UserToTransport对象,和视图要求类型匹配 ).ToList();
该方案无需修改原有视图代码。
方案2:视图需要同时展示UserToTransport和保险金额
如果需要在视图中读取保险的Amount字段,你需要新增视图模型承载两类数据:
- 新建视图模型类
namespace TransportRegistration { public class UserToTransportViewModel { public UserToTransport UserToTransport { get; set; } public decimal InsuranceAmount { get; set; } } }
- 修改控制器查询,投影为视图模型类型
var userToTransports = db.UserToTransports .Include(u => u.Transport) .Include(u => u.User) .Include(u => u.User1) .Where(u => u.User.Login.Equals(user)) .Join( db.Insurences, p => p.Transport_id, c => c.Transport_id, (p, c) => new UserToTransportViewModel { UserToTransport = p, InsuranceAmount = c.Amount } ).ToList();
- 修改视图的模型声明
@model IEnumerable<TransportRegistration.UserToTransportViewModel>
后续在视图中可以通过Model.FirstOrDefault().UserToTransport访问原关联数据,通过Model.FirstOrDefault().InsuranceAmount访问保险金额。
方案3:将保险设为UserToTransport的导航属性
如果希望后续可以直接通过导航属性加载保险数据,无需手写Join,你可以利用原有模型的partial特性扩展,避免自动生成代码被覆盖:
- 新建同命名空间的partial类扩展
UserToTransport
namespace TransportRegistration { public partial class UserToTransport { // 单个Transport对应一条保险记录用单个对象,对应多条用ICollection<Insurence> public virtual Insurence Insurence { get; set; } } }
- 在EF模型设计器中配置
UserToTransport和Insurence通过Transport_id建立外键关联,或者用Fluent API配置关系。 - 直接用Include加载导航属性即可,无需手写Join
var userToTransports = db.UserToTransports .Include(u => u.Transport) .Include(u => u.User) .Include(u => u.User1) .Include(u => u.Insurence) // 加载保险导航属性 .Where(u => u.User.Login.Equals(user)) .ToList();
该方案无需修改原有视图代码,还可以直接在视图中通过item.Insurence.Amount读取保险金额。
内容的提问来源于stack exchange,提问作者Bogdan Onyshenko
相关产品推荐
相关产品推荐

