ServiceStack.OrmLite 使用错误的列定义创建 table

ServiceStack.OrmLite Creating table with wrong column definition

我正在使用 ServiceStack.OrmLite,并且在尝试为 DateTime 设置默认列定义时,我无法设法使该列可以为空。其他一切都坚持,但“NULL”以某种方式转换为“NOT NULL”。

在我下面的示例代码中,我设置了 ColumnDefinition => "DATETIME(6) NULL DEFAULT... 并且当 运行 它时,它会创建一个 table 和 DATETIME(6) NOT NULL...

using ServiceStack.OrmLite;
using ServiceStack.OrmLite.Converters;
using System;
using System.Data;
using System.Linq;

OrmLiteConfig.OnModelDefinitionInit = a =>
{
    a.Alias = $"co_{a.ModelType.Name}";
    var idFieldDef = a.FieldDefinitions.Where(field => field.Name == "Id").First();
    idFieldDef.AutoIncrement = true;
    idFieldDef.AutoId = true;
};

MySqlDialect.Provider.RegisterConverter<DateTime>(new AlfaDateTimeConverter());
var factory = new OrmLiteConnectionFactory($"Uid=xxx;Password=yyy;Server=127.0.0.1;Port=3306;Database=ormtest", MySqlDialect.Provider);
var db = await factory.OpenDbConnectionAsync();
db.CreateTable<TestObject>();

public class AlfaDateTimeConverter : DateTimeConverter
{
    public override DbType DbType => DbType.DateTime;
    public override string ColumnDefinition => "DATETIME(6) NULL DEFAULT '0000-01-01 09:00:00'";
}

public class TestObject
{
    public long Id { get; set; }
    public DateTime Time { get; set; }
}

生成的 table 定义如下所示:

CREATE TABLE `co_testobject` (
    `Id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `Time` DATETIME(6) NOT NULL DEFAULT '0000-01-01 09:00:00.000000',
    PRIMARY KEY (`Id`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;

而且我这辈子都弄不清楚“NOT NULL”是从哪里来的。

显然,我非常独特的默认值仍然存在。

根据我的经验,MYSQL 会中止并让您知道您的陈述是否有问题。这不是尽力而为,MySQL 不会试图弄清楚你想要什么,也不会根据你的错误查询给你它可以提供的东西。要么你有一个格式正确的查询,要么你没有。

基于此,我假设发布到 MySQL 的创建语句包含“NOT NULL”。但这意味着 ServiceStack.OrmLite 是字符串解析我的 ColumnDefinition,在将它附加到完整的创建语句之前更改它。这听起来不太可能?

有什么想法吗?

如果要指定可为空的 ValueType RDBMS 列,它需要在 C# 类型上为 nullable,例如:

public class TestObject
{
    public long Id { get; set; }
    public DateTime? Time { get; set; }
}

OrmLite 从类型的元数据构建 RDBMS 列定义,它期望自定义类型转换器上的 ColumnDefinition 包含 RDBMS 列类型,即:

public class AlfaDateTimeConverter : DateTimeConverter
{
    public override DbType DbType => DbType.DateTime;
    public override string ColumnDefinition => "DATETIME(6)";
}

要指定默认值,您可以在 属性 上使用 [Default] 属性,或者您可以使用 OnModelDefinitionInit 以编程方式为所有 DateTime 类型填充它,例如:

OrmLiteConfig.OnModelDefinitionInit = modelDef => {
    modelDef.FieldDefinitions
        .Where(x => x.FieldType == typeof(DateTime))
        .Each(x => {
            x.DefaultValue = "'0000-01-01 09:00:00.000000'";
        });
};

您也可以在此处填充 IsNullable 元数据 属性,但如果 R​​DBMS 列是,DateTime? 应该可以为空。