如何使用LINQ从两张表查询字段?遇InvalidCastException报错
LINQ Join查询类型转换异常解决
错误信息
System.InvalidCastException: 'Unable to cast object of type '<>f__AnonymousType2
13[System.Int32,System.Nullable1[System.Int32],System.String,System.String,,System.Nullable1[System.DateTime],System.Nullable1[System.Int32],System.Nullable1[System.Decimal],System.Nullable1[System.DateTime],System.Nullable1[System.Decimal],System.Nullable1[System.Decimal]]' to type 'ProjectA.Models.Planting'.'
数据表结构
Planting表
| CropID | CropName | PlantDate | PlantQty | SiteID |
|---|---|---|---|---|
| 03 | Broccoli | 22/05/2017 | 100 | PlotA |
| 02 | Mango | 08/06/2017 | 20 | PlotD |
| 06 | Apple | 02/07/2018 | 20 | PlotF |
Harvest表
| Id | CropName | HarvestDate | Weight | CropID |
|---|---|---|---|---|
| 1 | Broccoli | 05/05/2024 | 2.00 | 03 |
| 2 | Mango | 07/05/2024 | 10.00 | 02 |
| 3 | Apple | 10/05/2024 | 4.00 | 06 |
尝试的代码
public class PlantingController : Controller { private readonly dbContext _context; public PlantingController(dbContext context) { _context = context; } public IActionResult Index() { return View(); } public IActionResult UrlDatasource([FromBody] DataManagerRequest dm) { IEnumerable DataSource = (from u in _context.Planting join c in _context.Harvest on u.CropID equals c.CropID select new { u.CropID, u.CropName, u.PlantDate, u.PlantQty, c.HarvestDate, c.Weight }); return dm.RequiresCounts ? Json(new { result = DataSource}) : Json(DataSource); } }
期望输出
| CropID | CropName | PlantDate | PlantQty | HarvestDate | Weight |
|---|---|---|---|---|---|
| 03 | Broccoli | 22/05/2017 | 100 | 05/05/2017 | 2.0 |
| 02 | Mango | 08/06/2017 | 20 | 07/05/2017 | 10.0 |
| 06 | Apple | 02/07/2018 | 20 | 10/05/2017 | 4.0 |
问题原因及解决方法
原因
查询返回的是匿名类型集合,但接收方(前端组件或数据绑定逻辑)试图将其强制转换为Planting实体类型,两者类型不匹配,导致转换异常。
解决方法
方法1:创建DTO类(推荐)
定义包含所需字段的DTO类,查询时返回该类型集合,避免匿名类型的类型转换问题:
// 定义DTO类 public class PlantingHarvestDto { public string CropID { get; set; } public string CropName { get; set; } public DateTime PlantDate { get; set; } public int PlantQty { get; set; } public DateTime HarvestDate { get; set; } public decimal Weight { get; set; } } // 修改控制器方法 public IActionResult UrlDatasource([FromBody] DataManagerRequest dm) { IEnumerable<PlantingHarvestDto> DataSource = (from u in _context.Planting join c in _context.Harvest on u.CropID equals c.CropID select new PlantingHarvestDto { CropID = u.CropID, CropName = u.CropName, PlantDate = u.PlantDate, PlantQty = u.PlantQty, HarvestDate = c.HarvestDate, Weight = c.Weight }); return dm.RequiresCounts ? Json(new { result = DataSource}) : Json(DataSource); }
方法2:适配匿名类型
如果前端组件允许接收匿名类型数据,检查组件配置,确保它不会尝试将返回的JSON数据强制转换为Planting类型。此方式适合快速测试,但DTO方式更利于代码维护和类型安全。
内容的提问来源于stack exchange,提问作者Milie24
相关产品推荐
相关产品推荐

