You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET+MySQL+NPoco下Lesson类IConvertible转换运行时错误求助

问题

使用.NET搭配MySQL与NPoco框架开发,已为Lesson类实现IConvertible接口,且包含无参构造函数与拷贝构造函数。通过.Query方法可成功读取其他表的数据,但读取Lesson表时,在LastDate字段处触发**「Object must implement IConvertible」**运行时错误,即使使用完整SQL查询也会出现该错误。MySQL中FirstDate与LastDate均为Date类型,FromDate字段无此问题。

数据库连接代码

_connectionString = "Server = 127.0.0.1; Database=test; user id=root; password=root;";
_connection = new MySqlConnection(_connectionString);
_connection.Open();

Lesson类代码

[TableName("lessons")] 
[PrimaryKey("id")]
public class Lesson : IConvertible 
{
    [Column("id")]
    public int? LessonId 
    { get; set; }
    
    [Column("first_date")]
    public DateTime FirstDate 
    { get; set; }
    
    [Column("last_date")]
    public DateTime LastDate
    { get; set; }  //  ERROR  here

    public Lesson() 
    {
        Console.WriteLine("Constructor Lesson");
    } 

    public Lesson(Lesson torahLesson)
    {
        LessonId = Lesson.LessonId;
        FirstDate = Lesson.FirstDate;
        LastDate = Lesson.LastDate;
    }
    
    static T ThrowNotSupported<T>()
    {
        var ex = ThrowNotSupported(typeof(T));
        return (T)ex;
    }

    static object ThrowNotSupported(Type type)
    {
        throw new InvalidCastException($"Converting type \"{typeof(Lesson)} \" to type \"{type}\" is not supported.");
    }

    TypeCode IConvertible.GetTypeCode()
    {
        return TypeCode.Object;
    }
    // 省略其他IConvertible接口方法实现
    DateTime IConvertible.ToDateTime(IFormatProvider provider) => ThrowNotSupported<DateTime>();
    // 省略其他接口方法
}

完整错误栈

at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at NPoco.MappingHelper.<>c__DisplayClass2_0.b__6(Object src)
at NPoco.RowMappers.PropertyMapper.MapValue(GroupResult`1 posName, Object[] values, Func`2 converter, Object instance, PocoColumn pocoColumn, Object defaultValue)
at NPoco.RowMappers.PropertyMapper.<>c__DisplayClass8_2.b__3(DbDataReader reader, Object[] values, Object instance)
at NPoco.RowMappers.PropertyMapper.<>c__DisplayClass7_0.b__1(DbDataReader reader, Object[] values, Object instance)
at NPoco.RowMappers.PropertyMapper.Map(DbDataReader dataReader, RowMapperContext context)
at NPoco.MappingFactory.Map(DbDataReader dataReader, Object instance)
at NPoco.Database.Read[T](Object instance, DbDataReader r, PocoData pd)+MoveNext()
at NPoco.Database.QueryImp[T](T instance, Expression`1 listExpression, Func`2 idFunc, Sql Sql, PocoData pocoData)+MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) 
at Avidov.Library.Server.Database.DbHelper.Query[T](Expression`1 whereExpression) in E:\MyData\Projects\Comp\LibraryDotNet\Comp.Library\Comp.Library.Serve\Database\DbHelper.cs:line 169
at Comp.Library.Server.Database.Repositories.LessonRepository.GetNotDeletedLessons(Int32 organizationId, Int32 year) in E:\MyData\Projects\Comp\LibraryDotNet\Comp.Library\Comp.Library.Serve\Database\Repositories\LessonRepository.cs:line 76
at Comp.Library.Server.LibraryManager.LessonsNumberDaysChanged(Int32 organizationId, DateTime createdAfterDate, Int32 budgetYear) in E:\MyData\Projects\Comp\LibraryDotNet\Comp.Library\Comp.Library.Serve\LibraryManager.cs:line 81
at Comp.Library.Client.Program.Main(String[] args) in E:\MyData\Projects\Comp\LibraryDotNet\Comp.Library\Comp.Library.Client\Program.cs:line 18
解决方案

问题根源

NPoco在映射数据库字段到实体属性时,会检测实体是否实现IConvertible接口。一旦发现该接口,NPoco会调用Convert.ChangeType方法处理字段值转换,但你的Lesson类中IConvertible.ToDateTime方法直接抛出了不支持转换的异常,导致LastDate(DateTime类型)在转换时触发错误。

FirstDate未触发错误是NPoco内部映射逻辑的偶然差异(比如字段顺序、缓存机制),核心问题是IConvertible接口的错误实现干扰了NPoco的默认类型转换流程。

解决方法

方法1:移除Lesson类的IConvertible接口实现

如果业务逻辑不需要Lesson类实现IConvertible,直接移除接口及相关实现即可:

[TableName("lessons")] 
[PrimaryKey("id")]
public class Lesson 
{
    // 保留原有属性、构造函数,删除所有IConvertible相关代码
}

方法2:正确实现IConvertible接口的ToDateTime方法

若必须保留IConvertible接口,需针对DateTime类型转换提供有效实现,避免抛出异常:

DateTime IConvertible.ToDateTime(IFormatProvider provider)
{
    // 根据业务需求返回正确的DateTime值,若无需转换整个实体到DateTime,可调整逻辑兼容NPoco的字段转换场景
    // 注意:NPoco调用Convert.ChangeType时传入的value是数据库字段值,而非Lesson实例,需匹配转换逻辑
    return DateTime.Now; // 示例值,需替换为实际业务逻辑
}

额外修正:拷贝构造函数语法错误

原拷贝构造函数存在逻辑错误,应使用传入的参数对象而非类本身:

public Lesson(Lesson torahLesson)
{
    LessonId = torahLesson.LessonId;
    FirstDate = torahLesson.FirstDate;
    LastDate = torahLesson.LastDate;
}

内容的提问来源于stack exchange,提问作者user3346475

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 13:35:31