3

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

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

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

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

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

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

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

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

I не сделалиenabled первых миграций кода (хотя по какой-то причине по-прежнему создается таблица __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 (right here). Я пробовал отслеживать код назад, но не могу сказать, вызывается ли GetBytes() для всех полей или только byte[] полей. (Первоначально я думал, что это может быть связано с полем __MigrationHistory.Model в базе данных, но ошибка по-прежнему возникает, если эта таблица пуста. Однако я не хочу, чтобы моя спекуляция вызывала неправильное направление.)

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

+0

Не могли бы вы включить трассировку стека в исключения? –

+0

@MarkRotteveel Я добавил трассировку стека и дополнительную информацию к сообщению. – vincentj

ответ

4

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

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

Я сделал что-то подобное для своего обходного пути. Инициализация теперь, кажется, работает правильно с Entity Framework 6.1, хотя теперь я получаю эту же ошибку, когда я использую Linq для запроса данных с параметром. Не уверен, что это одна и та же проблема, или я должен открыть новый вопрос (или отправить его непосредственно разработчикам Firebird). – vincentj