Sto provando a configurare un progetto con EF sopra un DB firebird ma sta generando citazioni extra che il db Firebird sta rifiutando.
Il db esiste già e vi è un record corrispondente per questa query lì. L'errore è FbException: Errore SQL dinamico Codice errore SQL = -104 Token sconosciuto - riga 2, colonna 4.
Tuttavia se rimuovo le virgolette che genera nel sql viene eseguita la query.
Esempio
using (var context = new ContextManager())
{
var accounts = context.Accounts.Where(x => x.OBJID == 1).ToList();
}
genera sql
SELECT
"A"."OBJID" AS "OBJID"
FROM "ACCOUNT" AS "A"
File di configurazione
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<entityFramework>
<defaultConnectionFactory type="FirebirdSql.Data.EntityFramework6.FbConnectionFactory, EntityFramework.Firebird" />
<providers>
<provider invariantName="FirebirdSql.Data.FirebirdClient" type="FirebirdSql.Data.EntityFramework6.FbProviderServices, EntityFramework.Firebird" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.data>
<DbProviderFactories>
<remove invariant="FirebirdSql.Data.FirebirdClient" />
<add name="FirebirdClient Data Provider" invariant="FirebirdSql.Data.FirebirdClient" description=".NET Framework Data Provider for Firebird" type="FirebirdSql.Data.FirebirdClient.FirebirdClientFactory, FirebirdSql.Data.FirebirdClient" />
</DbProviderFactories>
</system.data></configuration>
Classe di contesto
public class ContextManager : DbContext
{
public ContextManager() : base(new FbConnection("database=xxxx.fdb;DataSource=localhost;user=xxx;password=xxxxx"),true)
{
}
public ContextManager(string connString) : base(new FbConnection(connString), true)
{
//this.Configuration.LazyLoadingEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
public DbSet<Account> Accounts { get; set; }
}
Modello di conto
[Table("ACCOUNT")]
public class Account
{
[Key]
public int OBJID { get; set; }
}
Aggiornamento - verificato e visto il dialetto 1 è stato impostato in modo da aggiornare la stringa di query per denotarlo, la query non è stata modificata, ma l'errore è stato FbException: Errore SQL dinamico Codice errore SQL = -104 Token sconosciuto - riga 2, colonna 4.
Il problema è che il tuo database è dialect 1 e Entity Framework sta citando i nomi degli oggetti. Sfortunatamente i nomi degli oggetti citati non sono supportati in dialetto 1 e sono interpretati come stringhe. Questo porta agli errori sconosciuti del token, poiché il parser non si aspetta stringhe, ma nomi di oggetti.
È passato un po 'di tempo da quando ho fatto qualsiasi cosa con l'entity framework (di solito programma in Java), e non sono sicuro se c'è un'opzione per disabilitare la citazione.
Secondo questo ticket nel tracker bug di Firebird, il supporto di Firebird Entity Framework non supporta e non supporterà dialetto 1: DNET-580 .
Pertanto, a meno che non si aggiorni il database a dialect 3, sembra che non sarà possibile utilizzare Entity Framework. Tieni presente che l'aggiornamento dal dialetto 1 al dialetto 3 potrebbe non essere semplice, specialmente se le tue applicazioni si basano sulla sintassi specifica del dialetto 1 (ad esempio virgolette doppie per stringhe) o sul comportamento (divisione in virgola mobile per numeri interi).
Una possibile soluzione è specificare in modo esplicito la connessione dialect come dialect 3 (connection Dialect=3
per il provider Firebird ADO.net). Questo ti permetterà di interrogare il database usando la sintassi di dialect 3. Siate consapevoli che potrebbero esserci alcune differenze nel comportamento, in quanto il dialetto 3 ha un numero di regole diverse.
Sono un po 'sorpreso però, perché ho testato un numero di versioni recenti del provider ADO.net di Firebird e il suo valore predefinito è il dialetto 3, a meno che non sia impostato esplicitamente su 1, quindi questo non dovrebbe essere un problema.
Questa parte della risposta assume un database dialetto 3 in cui la tabella è effettivamente chiamato ACCOUNTS
, e non Accounts
. Ciò non risulterebbe in un token sconosciuto, ma in una tabella di errore sconosciuto.
In questa situazione, il problema è che la configurazione predefinita deriva i nomi dagli oggetti e citerà i nomi. I nomi quotati in dialetto 3 sono sensibili al maiuscolo / minuscolo (i nomi non quotati non fanno distinzione tra maiuscole e minuscole ma vengono memorizzati (e confrontati) in maiuscolo).
Quello che puoi fare è sovrascrivere il nome della tabella annotando il tuo oggetto:
[Table("ACCOUNTS")]
public class Account
{
[Key]
public int OBJID { get; set; }
}
Un'altra opzione che potresti usare è l'API fluente, ma non l'ho mai usata da sola, quindi non sono del tutto sicuro di dove devi specificarlo (credo nel tuo DbContext
).
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Changing Database table name to Metadata
modelBuilder.Entity<Account>()
.ToTable("ACCOUNTS");
}
Potrebbero esserci altre opzioni per influenzare le convenzioni di denominazione.
Vedere anche Entity Framework Code First - Modifica di un nome tabella