SqlSugar框架中SQLite默认值设置的注意事项

【免费下载链接】SqlSugar DotNetNext/SqlSugar: 这是一个用于SQL Server和MySQL的ORM框架。适合用于需要简化数据库操作的场景。特点:易于使用,支持多种数据库,具有代码生成和自动映射功能。 【免费下载链接】SqlSugar 项目地址: https://gitcode.com/DotNetNext/SqlSugar

引言

在数据库应用开发中,默认值(Default Value)是确保数据完整性和一致性的重要机制。然而,当使用SqlSugar ORM框架与SQLite数据库结合时,默认值的设置存在一些特殊的注意事项和限制。本文将深入探讨SqlSugar框架中SQLite默认值设置的完整指南,帮助开发者避免常见陷阱并充分利用框架功能。

SQLite默认值机制概述

SQLite作为轻量级嵌入式数据库,其默认值处理机制与其他关系型数据库有所不同:

mermaid

SqlSugar中的默认值配置

1. 启用SQLite默认值支持

SqlSugar默认不启用SQLite的默认值功能,需要通过配置显式开启:

var db = new SqlSugarClient(new ConnectionConfig()
{
    DbType = DbType.Sqlite,
    ConnectionString = "Data Source=test.db",
    InitKeyType = InitKeyType.Attribute,
    IsAutoCloseConnection = true,
    MoreSettings = new ConnMoreSettings()
    {
        SqliteCodeFirstEnableDefaultValue = true, // 必须显式启用
        SqliteCodeFirstEnableDescription = true
    }
});

2. 实体类中的默认值定义

使用[SugarColumn(DefaultValue = "...")]特性定义默认值:

public class User
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int Id { get; set; }
    
    [SugarColumn(DefaultValue = "'anonymous'")] // 字符串必须加单引号
    public string UserName { get; set; }
    
    [SugarColumn(DefaultValue = "0")] // 数字类型直接使用
    public int LoginCount { get; set; }
    
    [SugarColumn(DefaultValue = "(strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime'))")]
    public DateTime CreateTime { get; set; }
    
    [SugarColumn(DefaultValue = "false")] // 布尔值
    public bool IsDeleted { get; set; }
}

默认值设置的注意事项

1. 字符串默认值的引号问题

错误示例:

[SugarColumn(DefaultValue = "default")] // 错误:缺少单引号
public string Status { get; set; }

正确示例:

[SugarColumn(DefaultValue = "'active'")] // 正确:使用单引号
public string Status { get; set; }

2. 时间戳默认值的SQLite语法

SQLite不支持MySQL的NOW()或SQL Server的GETDATE(),必须使用SQLite特定的时间函数:

// 正确的时间默认值设置
[SugarColumn(DefaultValue = "CURRENT_TIMESTAMP")]
public DateTime CreateTime { get; set; }

// 或者使用strftime函数
[SugarColumn(DefaultValue = "(strftime('%Y-%m-%d %H:%M:%S', 'now'))")]
public DateTime CreateTime { get; set; }

// 带时区的设置
[SugarColumn(DefaultValue = "(strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime'))")]
public DateTime CreateTime { get; set; }

3. 默认值与NULL处理

public class Product
{
    [SugarColumn(IsNullable = true)] // 允许NULL
    public string Description { get; set; }
    
    [SugarColumn(IsNullable = false, DefaultValue = "'N/A'")] // 非空且有默认值
    public string Category { get; set; }
    
    [SugarColumn(IsNullable = true, DefaultValue = "NULL")] // 显式设置NULL默认值
    public string Notes { get; set; }
}

常见问题与解决方案

问题1:默认值不生效

原因: SqliteCodeFirstEnableDefaultValue配置未启用

解决方案:

// 确保在ConnectionConfig中启用默认值支持
MoreSettings = new ConnMoreSettings()
{
    SqliteCodeFirstEnableDefaultValue = true
}

问题2:迁移时默认值丢失

原因: SQLite的ALTER TABLE限制

解决方案:

// SqlSugar会自动处理列修改时的默认值迁移
db.CodeFirst.InitTables<User>(); // 自动维护表结构

问题3:默认值表达式错误

错误:

[SugarColumn(DefaultValue = "NOW()")] // SQLite不支持NOW()
public DateTime CreateTime { get; set; }

正确:

[SugarColumn(DefaultValue = "CURRENT_TIMESTAMP")]
public DateTime CreateTime { get; set; }

最佳实践指南

1. 默认值设置规范

数据类型 正确示例 错误示例 说明
字符串 "'default'" "default" 必须使用单引号
数字 "0", "1.5" "'0'" 直接使用数字
布尔 "true", "false" "'true'" 使用true/false
时间 "CURRENT_TIMESTAMP" "NOW()" 使用SQLite函数

2. 代码优先迁移策略

// 完整的Code First示例
public static void InitializeDatabase()
{
    using (var db = new SqlSugarClient(GetConfig()))
    {
        db.DbMaintenance.CreateDatabase();
        
        // 启用默认值支持
        db.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings()
        {
            SqliteCodeFirstEnableDefaultValue = true,
            SqliteCodeFirstEnableDescription = true
        };
        
        // 初始化表结构
        db.CodeFirst.InitTables<User, Product, Order>();
        
        Console.WriteLine("数据库初始化完成,默认值已设置");
    }
}

private static ConnectionConfig GetConfig()
{
    return new ConnectionConfig()
    {
        DbType = DbType.Sqlite,
        ConnectionString = "Data Source=app.db",
        InitKeyType = InitKeyType.Attribute,
        IsAutoCloseConnection = true
    };
}

3. 默认值验证测试

[Test]
public void TestDefaultValues()
{
    using (var db = new SqlSugarClient(GetConfig()))
    {
        // 插入数据时不提供有默认值的字段
        var user = new User { UserName = "test" };
        var id = db.Insertable(user).ExecuteReturnIdentity();
        
        // 查询验证默认值
        var result = db.Queryable<User>().InSingle(id);
        
        Assert.AreEqual("anonymous", result.UserName); // 字符串默认值
        Assert.AreEqual(0, result.LoginCount);        // 数字默认值
        Assert.IsFalse(result.IsDeleted);             // 布尔默认值
        Assert.IsNotNull(result.CreateTime);          // 时间默认值
    }
}

高级用法:动态默认值

1. 使用SQLite内置函数

public class AuditEntity
{
    [SugarColumn(DefaultValue = "CURRENT_TIMESTAMP")]
    public DateTime CreatedAt { get; set; }
    
    [SugarColumn(DefaultValue = "(strftime('%s', 'now'))")]
    public long Timestamp { get; set; }
    
    [SugarColumn(DefaultValue = "'system'")]
    public string CreatedBy { get; set; }
}

2. 条件默认值(通过触发器)

虽然SQLite不支持直接在列定义中使用条件默认值,但可以通过SqlSugar的AOP机制实现:

// 在SqlSugar配置中添加AOP处理
db.Aop.OnExecuting = (sql, paras) =>
{
    // 在插入前设置默认值
    if (sql.Contains("INSERT") && paras.ContainsKey("@Category"))
    {
        if (string.IsNullOrEmpty(paras["@Category"]?.ToString()))
        {
            paras["@Category"] = "Uncategorized";
        }
    }
};

性能优化建议

  1. 合理使用默认值:避免过度复杂的默认值表达式
  2. 批量操作优化:在批量插入时,让数据库处理默认值比代码设置更高效
  3. 索引考虑:为经常查询的带默认值的字段添加索引

总结

SqlSugar框架为SQLite数据库提供了完善的默认值支持,但需要开发者注意以下关键点:

  • ✅ 必须显式启用SqliteCodeFirstEnableDefaultValue配置
  • ✅ 字符串默认值必须使用单引号包裹
  • ✅ 时间默认值需使用SQLite特定的函数(CURRENT_TIMESTAMP等)
  • ✅ 充分利用SQLite的内置函数实现动态默认值
  • ✅ 通过AOP机制处理复杂的条件默认值需求

通过遵循本文的指南和最佳实践,开发者可以充分发挥SqlSugar和SQLite的组合优势,构建出既高效又可靠的数据持久层解决方案。

提示:在实际项目中,建议编写单元测试来验证默认值的正确性,确保数据库迁移和数据处理符合预期行为。

【免费下载链接】SqlSugar DotNetNext/SqlSugar: 这是一个用于SQL Server和MySQL的ORM框架。适合用于需要简化数据库操作的场景。特点:易于使用,支持多种数据库,具有代码生成和自动映射功能。 【免费下载链接】SqlSugar 项目地址: https://gitcode.com/DotNetNext/SqlSugar

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐