插入并返回实体会出错说Int32不能转成可空的Int64 返回

SqlSugar 沟通中
6 303
该叫什么 TheG 发布于1个月前
悬赏:0 飞吻

想请教一下,尝试了一个很简单的表,执行插入后就出错了,看起来是插入后返回时出错的,如果不加事务回滚的话,数据是可以插入成功的。


数据库为MySQL,使用SqlSugar自动建表

[HttpGet]
[Route("/Api/[controller]")]
public ResponseDto<object> Test()
{
    logger.LogInformation("Test");
    var db = provider.GetRequiredService<SqlSugarClient>();
    db.CodeFirst.InitTables(typeof(TestClass));

    using SugarUnitOfWork work = db.CreateContext();
    var test = new TestClass
    {
       DisplayName  = "测试显示",
       DisplayOrder = 10000,
       Status       = UserStatus.正常
    };
    test = db.Insertable<TestClass>(test).ExecuteReturnEntity();
    work.Commit();
    return ResponseDto<object>.Success(test);
}

[SugarTable("测试表")]
public class TestClass
{
    [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
    public long? Id { get; set; }
    [SugarColumn(ColumnName = "显示名", Length = 32)]
    public string? DisplayName { get; set; }
    [SugarColumn(ColumnName = "显示顺序")]
    public int? DisplayOrder { get; set; }
    [SugarColumn(ColumnName = "登录名", Length = 32)]
    public string? LoginName { get; set; }
    [SugarColumn(ColumnName = "密码", Length = 64)]
    public string? Password { get; set; }
    [SugarColumn(ColumnName = "密码盐", Length = 32)]
    public string? PasswordSalt { get; set; }
    [SugarColumn(ColumnName = "状态")]
    public UserStatus? Status { get; set; }
    [SugarColumn(ColumnName = "创建用户id")]
    public long? CreatorId { get; set; }
    [SugarColumn(ColumnName = "创建时间")]
    public DateTime? CreationTime { get; set; }
    [SugarColumn(ColumnName = "修改用户id")]
    public long? LastModifierId { get; set; }
    [SugarColumn(ColumnName = "修改时间")]
    public DateTime? LastModificationTime { get; set; }
}

public enum UserStatus
{
    正常 = 0,
    停用 = 1
}

执行上述代码,在正常执行建表语句后会输出下面的sql并抛出异常

[Sql]:INSERT INTO `测试表`  
           (`显示名`,`显示顺序`,`登录名`,`密码`,`密码盐`,`创建用户id`,`创建时间`,`修改用户id`,`修改时间`)
     VALUES
           (@显示名,@显示顺序,@登录名,@密码,@密码盐,@创建用户id,@创建时间,@修改用户id,@修改时间) ;SELECT LAST_INSERT_ID(); 
[Pars]:
[Name]:@显示名 [Value]:测试显示 [Type]:String    
[Name]:@显示顺序 [Value]:10000 [Type]:Int32    
[Name]:@登录名 [Value]: [Type]:String    
[Name]:@密码 [Value]: [Type]:String    
[Name]:@密码盐 [Value]: [Type]:String    
[Name]:@创建用户id [Value]: [Type]:Int64    
[Name]:@创建时间 [Value]: [Type]:DateTime    
[Name]:@修改用户id [Value]: [Type]:Int64    
[Name]:@修改时间 [Value]: [Type]:DateTime

 An unhandled exception has occurred while executing the request.
System.ArgumentException: Object of type 'System.Int32' cannot be converted to type 'System.Nullable`1[System.Int64]'.
   at System.RuntimeType.CheckValue(Object& value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at SqlSugar.InsertableProvider`1.ExecuteCommandIdentityIntoEntity()
   at SqlSugar.InsertableProvider`1.ExecuteReturnEntity()
   at G.Main.TestController.Test() in /Users/dengjunwen/本地项目/学习/CSharp1/CSharpG/G.Main/TestController.cs:line 32
   at lambda_method1(Closure, Object, Object[])
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

SqlSugar的配置代码如下

public static void AddSqlSugarSetup(this IServiceCollection services)
{
    string connectionString = ApplicationContext.AppSetting.SquSugar.ConnectionString;
    var config = new ConnectionConfig
    {
       ConnectionString      = connectionString,
       DbType                = DbType.MySql,
       IsAutoCloseConnection = true,
       ConfigureExternalServices = new ConfigureExternalServices
       {
          EntityService = (propertyInfo, columnInfo) =>
          {
             //可空类型且不是主键,则数据库可空
             if (! columnInfo.IsPrimarykey
                && new NullabilityInfoContext().Create(propertyInfo).WriteState is NullabilityState.Nullable)
                columnInfo.IsNullable = true;
          }
       }
    };
    var client = new SqlSugarClient(config);

    services.AddScoped<SqlSugarClient>(s =>
    {
       ILogger logger = Log.ForContext(typeof(SqlSugarSetup));
       client.Aop.OnLogExecuted = (sql, pars) =>
       {
          logger.Debug("执行sql:{已执行SQL}", UtilMethods.GetNativeSql(sql, pars));
          // Console.WriteLine($"执行sql:{UtilMethods.GetNativeSql(sql, pars)}");
       };
       return client;
    });
    services.AddScoped<TransactionActionFilter>();
    services.AddScoped(typeof(BaseRepository<>));

    WhenUpdatable();
}

private static void WhenUpdatable()
{
    StaticConfig.CompleteUpdateableFunc = o =>
    {
       if (o is IUpdateable<object> updateable)
          updateable.IgnoreColumns(true, ignoreAllDefaultValue: true);
       else
          throw new GAppException($"注册全局SqlSugar更新对象事件时类型异常【{o.GetType().FullName}】");
    };
}


热忱回答6

  • TheG TheG VIP0
    1个月前

    似乎是ExecuteReturnEntity方法跟long?类型的主键之间存在不兼容?如果使用long类型的主键或者使用ExecuteReturnBigIdentity的话就不会报错,不过这是为什么呢,是Bug还是Feature

    0 回复
  • 《%》 《%》 VIP0
    1个月前

    image.png哥们主键能为空吗


    0 回复
  • fate sta fate sta VIP0
    1个月前

    image.png


    我这边测试正常

    0 回复
  • fate sta fate sta VIP0
    1个月前
    using SqlSugar;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace OrmTest
    {
        internal class Uintzdfa2
        {
            public static void Init() 
            {
                var db = NewUnitTest.Db;
                db.CodeFirst.InitTables(typeof(TestClass));
    
                using SugarUnitOfWork work = db.CreateContext();
                var test = new TestClass
                {
                    DisplayName = "测试显示", 
                };
                test = db.Insertable<TestClass>(test).ExecuteReturnEntity();
                work.Commit();
            }
            
    
            [SugarTable("Unitdfsdf2")]
            public class TestClass
            {
                [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
                public long  Id { get; set; }
                [SugarColumn(ColumnName = "显示名", Length = 32)]
                public string  DisplayName { get; set; }
      
            }
    
            public enum UserStatus
            {
                正常 = 0,
                停用 = 1
            }
        }
    }


    0 回复
  • TheG TheG VIP0
    1个月前

    @《%》:我想的是自增主键我插入前应该是null所以允许可null呀

    0 回复
  • TheG TheG VIP0
    1个月前

    @fate sta:我发现是主键可空的问题,而且跟执行的方法有关系,换成用ExecuteReturnBigIdentity插入并给实体的主键赋值就正常了

    我之前用ExecuteReturnEntity是想说如果有数据库默认值的话可以读回来

    0 回复