EF 6 和 Oracle 使用 Guid 作为主键

本文关键字:Guid 使用 Oracle EF | 更新日期: 2023-09-27 18:32:16

在我们的应用程序(ASP.NET MVC 5)中,我们将EF 6代码优先与SQL Server一起使用。现在我们需要使用Oracle DB运行它(我们的客户不信任SQL Server)。

我们已经设法让一个小型测试项目正常工作,但我们在迁移实际应用程序时遇到了一些问题。

我们还无法解决的一个问题是使用 Guid 作为主键(我们所有的类都有一个Guid作为主键)。

像这样:

public class TestModel
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid TestModelId { get; set; }
}

如果我们使用上面的代码运行Update-Database,我们会得到以下异常:

Identity-Spalte muss einen numerischen Typ aufweisen = Identity-Column Must be a numeric type

Oracle.ManagedDataAccess.Client.OracleException (0x000077D3): ORA-30675: Identity-Spalte muss einen numerischen Typ aufweisen
ORA-30675: Identity-Spalte muss einen numerischen Typ aufweisen

我们试图通过告诉 Oracle/EF 将类型为 RAW(16) 的字段来解决此问题:

protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
    modelBuilder.Entity<TestModel>()
                .ToTable("TESTMODEL", "MySchema");
    modelBuilder.Entity<TestModel>()
                .Property( x => x.TestModelId )
                .HasColumnType( "RAW(16)" );
}

运行更新数据库后,我们收到以下异常(不是很有帮助...至少对我们来说):

System.InvalidOperationException: 序列不包含匹配的元素

唯一有效的似乎是删除DatabaseGeneratedAttribute和类型映射:

public class TestModel
{
     [Key]
     //[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
     public Guid TestModelId { get; set; }
}
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
    modelBuilder.Entity<TestModel>()
                .ToTable("TESTMODEL", " MySchema");
    /*modelBuilder.Entity<TestModel>()
                .Property( x => x.TestModelId )
                .HasColumnType( "RAW(16)" );*/
}

这将生成一个表,如下所示:

+----------------------------------+
| Name        | DataType | NotNull |
+----------------------------------+
| TestModelId | RAW(16)  | True    |
+----------------------------------+

但是如果没有DatabaseGeneratedAttribute我们必须手动为模型提供一个主键......我们不想这样做。

我们如何使用 Guid 作为主键,DatabaseGenerated(DatabaseGeneratedOption.Identity)使用 Oracle 数据库?

我们正在使用:

  • EF 6.1.1
  • Oracle.ManagedDataAccess 4.121.1.0 (ODAC 12c Release 3)
  • Oracle.ManagedDataAccess.EntityFramework 6.121.1.0 (ODAC 12c Release 3)

我们的配置 ( web.config ):

<configuration>
  <configSections>
    <section name="entityFramework"
             type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
             requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="Model1" connectionString="DATA SOURCE=ORCL;PASSWORD=PASSWORD;PERSIST SECURITY INFO=True;USER ID=USER"
         providerName="Oracle.ManagedDataAccess.Client" />
  </connectionStrings>
  <entityFramework>
    <providers>
      <provider invariantName="Oracle.ManagedDataAccess.Client"
                type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="Oracle.ManagedDataAccess.Client" />
      <add name="Oracle Data Provider for .NET" description="Oracle Data Provider for .NET"
           invariant="Oracle.ManagedDataAccess.Client"
           type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    </DbProviderFactories>
  </system.data>
</configuration>

EF 6 和 Oracle 使用 Guid 作为主键

我有类似的问题,并尝试使用Adriano Repetti的建议,即在构造函数中添加"Guid.NewGuid()"。它工作得很好!