“未知数据类型"Firebird 嵌入式和实体框架 6 出错 [英] "Unknown data type" error with Firebird embedded and Entity Framework 6

查看:16
本文介绍了“未知数据类型"Firebird 嵌入式和实体框架 6 出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有代码的嵌入式 Firebird 数据库(实体框架 6).应用程序第一次运行时,它运行良好:创建数据库并插入数据.但之后每次运行时,都会抛出以下异常:

I'm using an embedded Firebird database with code first (Entity Framework 6). The first time the application runs, it works fine: the database gets created and the data gets inserted. But every time it runs after that, it throws the following exception:

System.NotSupportedException"类型的异常发生在FirebirdSql.Data.FirebirdClient.dll 但未在用户代码中处理

An exception of type 'System.NotSupportedException' occurred in FirebirdSql.Data.FirebirdClient.dll but was not handled in user code

附加信息:未知数据类型

Additional information: Unknown data type

该项目包括以下 NuGet 包:

The project includes the following NuGet packages:

  • EntityFramework [6.0.2]
  • Firebird ADO.NET 数据提供程序(实体框架 6)[4.1.0.0]

我将 DbProviderFactoriesFirebirdSql.Data.FirebirdClient 提供程序添加到 App.config 中,如 这里.

I added the DbProviderFactories and FirebirdSql.Data.FirebirdClient provider to App.config as described here.

我还将 Firebird DLL 添加到项目中并将它们设置为复制到输出目录:

I also added the Firebird DLLs to the project and set them to copy to the output directory:

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

没有 启用代码第一次迁移(尽管 __MigrationHistory 表仍因某种原因被创建).

I have not enabled code first migrations (though the __MigrationHistory table still gets created for some reason).

代码如下:

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:UsersJiriDocumentsdevelNETProviderworkingNETProvidersourceFirebirdSqlDataCommonDbValue.cs:line 315
at FirebirdSql.Data.Client.Common.XsqldaMarshaler.MarshalManagedToNative(Charset charset, Descriptor descriptor) in c:UsersJiriDocumentsdevelNETProviderworkingNETProvidersourceFirebirdSqlDataClientCommonXsqldaMarshaler.cs:line 121
at FirebirdSql.Data.Client.Native.FesStatement.Execute() in c:UsersJiriDocumentsdevelNETProviderworkingNETProvidersourceFirebirdSqlDataClientNativeFesStatement.cs:line 355
at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(CommandBehavior behavior, Boolean returnsSet) in c:UsersJiriDocumentsdevelNETProviderworkingNETProvidersourceFirebirdSqlDataFirebirdClientFbCommand.cs:line 1246
at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteReader(CommandBehavior behavior) in c:UsersJiriDocumentsdevelNETProviderworkingNETProvidersourceFirebirdSqlDataFirebirdClientFbCommand.cs:line 566
at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteDbDataReader(CommandBehavior behavior) in c:UsersJiriDocumentsdevelNETProviderworkingNETProvidersourceFirebirdSqlDataFirebirdClientFbCommand.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() 还是只为 byte[] 字段调用.(我最初认为它可能与数据库中的 __MigrationHistory.Model 字段有关,但如果该表为空,仍然会出现错误.但是,我不希望我的猜测导致误导.)

The stack trace points to the Firebird library (right here). I tried tracing the code backwards but I can't tell if GetBytes() is called for all fields or just byte[] fields. (I initially thought that it might be related to the __MigrationHistory.Model field in the database, but the error still occurs if that table is empty. However, I don't want my speculation to cause misdirection.)

我可以解决这个问题,但我真的很想了解它.有谁知道这里发生了什么?

I could hack around the issue, but I'd really like to understand it. Does anyone know what's happening here?

推荐答案

我遇到了同样的问题,实体初始化程序被 Firebird 嵌入了错误:

I Had the same problem, The Entity initializer is bugged with Firebird embedded:

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

是问题,改成:

Database.SetInitializer<FirebirdDbContext>(null);

但它不会为您创建数据库.您可以检查数据库文件是否存在,然后更改初始化程序.

But it will not create the database for you. You could check if the database file existis then change de initializer.

或者你可以创建你的初始化器来做同样的事情,并且可以工作:

or you can create your initializer that does tha same, and works:

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

这篇关于“未知数据类型"Firebird 嵌入式和实体框架 6 出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆