Ошибка «Неизвестный тип данных» с встроенной Firebird и Entity Framework 6

c# ef-code-first entity-framework-6 firebird firebird-embedded

Вопрос

Сначала я использую встроенную базу данных Firebird с кодом (Entity Framework 6). При первом запуске приложения он отлично работает: создается база данных и вставляются данные. Но каждый раз после этого он выдает следующее исключение:

Исключение типа «System.NotSupportedException» произошло в FirebirdSql.Data.FirebirdClient.dll, но не было обработано в коде пользователя

Дополнительная информация: Неизвестный тип данных

Проект включает следующие пакеты NuGet:

  • EntityFramework [6.0.2]
  • Поставщик данных Firebird ADO.NET (Entity Framework 6) [4.1.0.0]

Я добавил DbProviderFactories и FirebirdSql.Data.FirebirdClient провайдера в App.config как описано здесь .

Я также добавил DLL Firebird в проект и установил их для копирования в выходной каталог:

  • fbembed.dll
  • ib_util.dll
  • icudt30.dll
  • icuin30.dll
  • icuuc30.dll

Я не включил первые миграции кода (хотя по какой-то причине по-прежнему __MigrationHistory таблица __MigrationHistory ).

Вот код:

class Program
{
    static void Main(string[] args)
    {
        Database.SetInitializer<FirebirdDbContext>(new CreateDatabaseIfNotExists<FirebirdDbContext>());
        string connectionString = "server type=Embedded;user id=sysdba;password=masterkey;role name=RDB$ADMIN;character set=UTF8;initial catalog=test.fdb";

        using (var context = new FirebirdDbContext(connectionString))
        {
            context.Users.Add(new User()
                { Created = DateTime.Now,
                    Name = "smith" });
            context.SaveChanges();
        }
    }
}

class User
{
    [Key]
    public DateTime Created { get; set; }

    public string Name { get; set; }
}

class FirebirdDbContext : DbContext
{
    public FirebirdDbContext(string connString)
        : base(new FbConnection(connString), true) { }

    public DbSet<User> Users { get; set; }
}

class MyConfiguration : DbConfiguration
{
    public MyConfiguration() 
    {
        SetDefaultHistoryContext((c, s) => new SmallKeyHistoryContext(c, s));
    }
}

class SmallKeyHistoryContext : HistoryContext
{
    public SmallKeyHistoryContext(DbConnection existingConnection, string defaultSchema)
        : base(existingConnection, defaultSchema) { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        // HACK: Make this column smaller to avoid the following error:
        // key size exceeds implementation restriction for index "PK___MigrationHistory"
        modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(53).IsRequired();
    }
}

Исключение выбрасывается на строку context.Users.Add(...) .

Вот трассировка стека :

at FirebirdSql.Data.Common.DbValue.GetBytes() in c:\Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\Common\DbValue.cs:line 315
at FirebirdSql.Data.Client.Common.XsqldaMarshaler.MarshalManagedToNative(Charset charset, Descriptor descriptor) in c:\Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\Client\Common\XsqldaMarshaler.cs:line 121
at FirebirdSql.Data.Client.Native.FesStatement.Execute() in c:\Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\Client\Native\FesStatement.cs:line 355
at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(CommandBehavior behavior, Boolean returnsSet) in c:\Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\FirebirdClient\FbCommand.cs:line 1246
at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteReader(CommandBehavior behavior) in c:\Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\FirebirdClient\FbCommand.cs:line 566
at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteDbDataReader(CommandBehavior behavior) in c:\Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\FirebirdClient\FbCommand.cs:line 666
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<>c__DisplayClassb.<Reader>b__8()
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](Func`1 operation, TInterceptionContext interceptionContext, Action`1 executing, Action`1 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)

Трассировка стека указывает на библиотеку Firebird ( прямо здесь ). Я пробовал отслеживать код назад, но не могу определить, GetBytes() ли GetBytes() для всех полей или только byte[] . (Первоначально я думал, что это может быть связано с полем __MigrationHistory.Model в базе данных, но ошибка все равно возникает, если эта таблица пуста. Однако я не хочу, чтобы мои предположения вызывали неправильное направление.)

Я мог бы взломать проблему, но я бы очень хотел ее понять. Кто-нибудь знает, что здесь происходит?

Принятый ответ

Я имел ту же проблему, инициализатор Entity прослушивается с встроенным Firebird:

Database.SetInitializer<FirebirdDbContext>(new CreateDatabaseIfNotExists<FirebirdDbContext>()); 

это проблема, измените ее на:

Database.SetInitializer<FirebirdDbContext>(null);

Но он не будет создавать базу данных для вас. Вы можете проверить, существует ли файл базы данных, а затем изменить инициализатор.

или вы можете создать свой инициализатор, который делает то же самое, и работает:

public class MyCreateDatabaseIfNotExists : IDatabaseInitializer<FirebirdDbContext>
{
    public void InitializeDatabase(FirebirdDbContext context)
    {
        if (!context.Database.Exists())
        {
            context.Database.Create();
        }
    }
}


Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему