EF 6 и Oracle используют Guid в качестве первичного ключа

1

В нашем приложении (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 numischen Тип aufweisen = Identity-Column должен быть числовым типом

Oracle.ManagedDataAccess.Client.OracleException(0x000077D3): ORA-30675: Identity-Spalte muss einen numischen Тип aufweisen
ORA-30675: Identity-Spalte muss einen numischen Тип 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: Последовательность не содержит соответствующего элемента

Единственное, что работает, похоже, заключается в удалении атрибута 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>
  • 2
    Я думаю, что с EF у вас не может быть GUID в качестве идентификатора, сгенерированного базой данных (AFAIK!), В коде сначала просто добавьте Guid.NewGuid () в конструктор вашего класса.
  • 0
    С SQL Server GUID в качестве идентификатора базы данных работает отлично .. это ограничение Oracle?
Показать ещё 1 комментарий
Теги:
entity-framework
ef-code-first

1 ответ

-1

У меня есть аналогичная проблема и я попытался использовать предложение Адриано Репетти, которое должно добавить "Guid.NewGuid()" в конструкторе. Это сработало отлично!

  • 0
    Это должен быть комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню