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