【问题标题】:OrmLite - GUIDs as primary keys in OracleOrmLite - GUID 作为 Oracle 中的主键
【发布时间】:2018-11-17 08:24:22
【问题描述】:

我将 OrmLite 与 SqlServer、Oracle 和 PostgreSQL 方言一起使用。

我想使用 GUID 作为主键并拥有一个简单的对象,使用 AutoId 属性:

public class MyObject
{
    [AutoId]
    public Guid Id { get; set; }
    [Required]
    public string Name { get; set; }
    ...

SqlServer 和 PostgreSQL dialetcs 一切顺利,但使用 Oracle,我得到一个初始 GUID,数据库中全为零,随后的 INSERT 违反了我的主键的唯一键约束。如何做到这一点与 db 无关,因此它也可以与 Oracle 一起使用?

【问题讨论】:

  • 我在 this commit 的 OrmLite 的 Oracle DialectProvider 中添加了使用 SYS_GUID 的 @TonyMorris 解决方案。此更改从 v5.4.1 开始可用,现在为 available on MyGet

标签: ormlite-servicestack


【解决方案1】:

根据我正在查看的源代码,无论README 上的文档实际说明了什么,它似乎都无法为任何不是 SQL Server 或 PostgreSQL 的东西正确生成 GUID。相关代码链接如下:


我可以在这里提供的最佳选择是覆盖OracleOrmLiteDialectProvider。具体来说,如果字段类型是 GUID,我将覆盖 GetAutoIdDefaultValue 方法以返回 "SYS_GUID()"。下面的示例代码...

public OracleNewGuidOrmLiteDialectProvider : OracleOrmLiteDialectProvider
{
    public static OracleNewGuidOrmLiteDialectProvider Instance = new OracleNewGuidOrmLiteDialectProvider();
    public string AutoIdGuidFunction { get; set; } = "SYS_GUID()";

    public override string GetAutoIdDefaultValue(FieldDefinition fieldDef)
    {
        return fieldDef.FieldType == typeof(Guid)
            ? AutoIdGuidFunction
            : null;
    }   
}

为了匹配其余的提供者实现,我建议创建一个OracleNewGuidDialect 类,如下所示...

public static class OracleNewGuidDialect
{
    public static IOrmLiteDialectProvider Provider => OracleNewGuidOrmLiteDialectProvider.Instance;
}

然后,当您将OrmLiteConnectionFactory 实例化为OracleNewGuidOrmLiteDialectProvider.Instance 时,您将设置提供程序,类似于下面...

var dbFactory = new OrmLiteConnectionFactory(oracleConnectionString, OracleNewGuidDialect.Provider);

这不是最好的解决方案,但 ServiceStack ORMLite 的可插拔特性允许您在需要的范围内控制一切。希望这可以帮助。另外,请注意——我没有完全烘焙此解决方案,因此您可能需要对其进行调整,但基于提供程序的其他实现,这似乎很简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    相关资源
    最近更新 更多