EF 6和Oracle使用Guid作为主键

时间:2014-11-28 09:59:58

标签: c# oracle entity-framework ef-code-first

在我们的应用程序(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必须是数字类型

     

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)" );
}

运行Update-Database后,我们收到以下异常(至少对我们来说不是很有帮助):

  

System.InvalidOperationException:Sequence不包含匹配元素

唯一有效的方法似乎是删除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第3版)
  • Oracle.ManagedDataAccess.EntityFramework 6.121.1.0(ODAC 12c第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>

1 个答案:

答案 0 :(得分:-1)

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