"未知数据类型"与火鸟错误嵌入式和Entity Framework 6 [英] "Unknown data type" error with Firebird embedded and Entity Framework 6

查看:190
本文介绍了"未知数据类型"与火鸟错误嵌入式和Entity Framework 6的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的代码嵌入Firebird数据库第一(实体框架6)。该应用程序第一次运行时,它工作正常:数据库中获取创建,得到的数据插入。但每次之后运行时,它抛出以下异常:




System.NotSupportedException类型的异常出现在
FirebirdSql.Data.FirebirdClient.dll但在用户代码中没有处理



更多信息:未知的数据类型。




该项目包括以下的NuGet包:




  • 的EntityFramework [6.0.2]

  • 火鸟ADO.NET数据提供商(实体框架6)[4.1.0.0]



我添加了 DbProviderFactories FirebirdSql.Data.FirebirdClient 提供商的App.config 作为 rel=\"nofollow\">。



我还添加了火鸟的DLL到项目,并设置它们复制到输出目录:




  • fbembed.dll

  • ib_util.dll

  • icudt30.dll

  • icuin30.dll

  • icuuc30.dll



我还没有启用代码首先迁移(虽然 __ MigrationHistory 表仍然获取创建。某些原因)



下面的代码:



<预类=郎-CS prettyprint-覆盖> 类节目
{
静态无效的主要(字串[] args)
{
Database.SetInitializer< FirebirdDbContext>(新CreateDatabaseIfNotExists< FirebirdDbContext>());
字符串的connectionString =服务器类型=嵌入式;用户ID = SYSDBA;密码= masterkey,角色名称= RDB $ ADMIN;字符集= UTF8;初始目录= test.fdb;

使用(VAR上下文=新FirebirdDbContext(的connectionString))
{
context.Users.Add(新用户()
{创建= DateTime.Now,
产品名称=史密斯});
context.SaveChanges();
}
}
}

类用户
{
[关键]
公众的DateTime创建{搞定;组; }

公共字符串名称{;组; }
}

类FirebirdDbContext:的DbContext
{
公共FirebirdDbContext(字符串CONNSTRING)
:基地(新FbConnection(CONNSTRING),真){}

公共DbSet<使用者>用户{搞定;组; }
}

类MyConfiguration:DbConfiguration
{
公共MyConfiguration()
{
SetDefaultHistoryContext((C,S)=>新SmallKeyHistoryContext(C,S));
}
}

类SmallKeyHistoryContext:HistoryContext
{
公共SmallKeyHistoryContext(的DbConnection existingConnection,串defaultSchema)
:基地(existingConnection,defaultSchema ){}

保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
{
base.OnModelCreating(模型构建器);
// HACK:请此列小,以避免以下错误:
//密钥大小超过执行限制索引PK___MigrationHistory
modelBuilder.Entity< HistoryRow>()房产(小时。 => h.ContextKey).HasMaxLength(53).IsRequired();
}
}

的异常被扔在了 context.Users.Add(...)



下面是在堆栈跟踪

 在FirebirdSql.Data.Common.DbValue.GetBytes(c)中:\Users\Jiri\Documents\devel\ NETProvider\working\NETProvider\source\FirebirdSql\Data\Common\DbValue.cs:在FirebirdSql.Data.Client.Common.XsqldaMarshaler.MarshalManagedToNative线315 
(字符集字符集,描述符描述符)在C:\Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\Client\Common\XsqldaMarshaler.cs:线121
。在FirebirdSql.Data.Client.Native.FesStatement.Execute(c)中:\Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\ Client\Native\FesStatement.cs:在FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(的CommandBehavior行为,布尔returnsSet)在C线355
:\Users\Jiri\Documents\devel\ NETProvider\working\NETProvider\source\FirebirdSql\Data\FirebirdClient\FbCommand.cs:在FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteReader(的CommandBehavior行为)在C线1246
:\ Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\FirebirdClient\FbCommand.cs:在FirebirdSql.Data.FirebirdClient线566
。 FbCommand.ExecuteDbDataReader在C(的CommandBehavior行为):\Users\Jiri\Documents\devel\NETProvider\working\NETProvider\source\FirebirdSql\Data\FirebirdClient\FbCommand.cs:行666
。在System.Data.Common.DbCommand.ExecuteReader(的CommandBehavior行为)所述
。在System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher&;方式> c__DisplayClassb&所述;读者与GT; b__8()$在System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch [TInterceptionContext,TResult] b $ b(Func`1操作,TInterceptionContext interceptionContext,Action`1执行,执行Action`1)在系统
。 Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(的DbCommand命令,DbCommandInterceptionContext interceptionContext)
在System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(的CommandBehavior行为)
在System.Data.Common.DbCommand .ExecuteReader(的CommandBehavior行为)
在System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(entityCommand entityCommand,行为的CommandBehavior)

堆栈跟踪指向火鸟库(的在这里)。我试着向后跟踪代码,但我不能告诉,如果 GetBytes会()被调用的所有字段或仅字节[] 字段。 (我最初以为,这可能会在数据库中有关 __ MigrationHistory.Model 字段,但如果该表是空的仍然出现错误,但我不希望我的猜测造成误导。)



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


解决方案

我有同样的问题,实体初始化器窃听与火鸟嵌入式:

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

的问题,将其更改为:

  Database.SetInitializer< FirebirdDbContext>(NULL); 



但它不会为你创建数据库。你可以检查数据库文件existis然后换去初始化



也可以创建你的初始化,做塔一样,和作品:

 公共类MyCreateDatabaseIfNotExists:IDatabaseInitializer< FirebirdDbContext> 
{
公共无效InitializeDatabase(FirebirdDbContext上下文)
{
如果(!context.Database.Exists())
{
context.Database.Create ();
}
}
}


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:

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

Additional information: Unknown data type

The project includes the following NuGet packages:

  • EntityFramework [6.0.2]
  • Firebird ADO.NET Data provider (Entity Framework 6) [4.1.0.0]

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

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

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

Here's the code:

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

The exception gets thrown on the context.Users.Add(...) line.

Here's the stack trace:

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)

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?

解决方案

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

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

is the problem, change it to:

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

这篇关于&QUOT;未知数据类型&QUOT;与火鸟错误嵌入式和Entity Framework 6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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