"Unknown data type" Firebird 嵌入式和实体框架 6 的错误



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

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

附加信息:未知数据类型

该项目包括以下NuGet包:

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

我将DbProviderFactoriesFirebirdSql.Data.FirebirdClient提供程序添加到App.config中,如下所述。

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

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

I尚未启用代码优先迁移(尽管由于某些原因,__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: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字段有关,但如果该表为空,错误仍然会发生。但是,我不希望我的猜测造成误导。)

我可以绕过这个问题,但我真的很想了解它。有人知道这里发生了什么吗?

我也遇到了同样的问题,实体初始化器被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();
}
}
}

相关内容

  • 没有找到相关文章

最新更新