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
元数据 属性,但如果 RDBMS 列是,DateTime?
应该可以为空。
我正在使用 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
元数据 属性,但如果 RDBMS 列是,DateTime?
应该可以为空。