"未知数据类型"与火鸟错误嵌入式和Entity Framework 6 [英] "Unknown data type" error with Firebird embedded and 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
andFirebirdSql.Data.FirebirdClient
provider toApp.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 justbyte[]
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(); } } }
这篇关于"未知数据类型"与火鸟错误嵌入式和Entity Framework 6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!