使用Dapper查询Ticket实体时因无参构造函数缺失引发实例化异常
解决Dapper查询Ticket实体时的实例化异常
问题原因
- 构造函数签名不匹配:数据库表
ticket包含Id字段(异常提示中明确提及),但你的Ticket类未定义该属性,且构造函数也未包含Id参数。Dapper执行SELECT *会返回所有字段,尝试用这些字段值匹配构造函数时找不到对应签名。 - 字段名称不匹配:数据库中的
date字段与实体类的TravelDate属性名称不一致,Dapper默认按名称映射,导致无法正确绑定。 - 类型不匹配:数据库中
price字段是数值类型(Decimal/Double),但实体类中Price定义为string类型,构造函数参数也是string,类型不兼容导致无法实例化。
解决方案
方案1:调整Ticket实体类适配Dapper映射
修改Ticket类,解决构造函数、字段名和类型问题:
public class Ticket { // 添加无参构造函数,供Dapper实例化使用 private Ticket() { } // 保留业务构造函数,同步修改Price类型为decimal匹配数据库 public Ticket(string origin, string destination, decimal price, DateTime travelDate) { Origin = origin; Destination = destination; Price = price; TravelDate = travelDate; } // 若数据库表有Id字段,可根据业务需求添加该属性(可选) // public int Id { get; private set; } public string Origin { get; private set; } public string Destination { get; private set; } // 将Price类型改为decimal,匹配数据库的数值类型 public decimal Price { get; private set; } // 使用Column特性指定数据库字段名,解决date与TravelDate的映射差异 [Column("date")] public DateTime TravelDate { get; private set; } }
同步修改AddTicketRepository中Price的参数配置(因实体类型变更):
parameters.Add("price", ticket.Price, System.Data.DbType.Decimal);
方案2:修改查询语句适配现有实体类
如果不想修改实体类,可调整SELECT语句,明确字段并设置别名,排除不需要的Id字段,同时转换price类型:
public List<Ticket> GetTickets() { // 排除Id字段,将date别名设为TravelDate,price转为字符串匹配实体类型 var query = @"SELECT origin, destination, CAST(price AS VARCHAR) AS price, date AS TravelDate FROM ticket"; using var connection = _dbContext.CreateConnection(); var tickets = connection.Query<Ticket>(query).ToList(); return tickets; }
内容的提问来源于stack exchange,提问作者Ederson Dias
相关产品推荐
相关产品推荐

