7

Sto provando a convertire un progetto che utilizza attualmente un framework DAO personalizzato per l'utilizzo di Entity Framework. Il sistema è abbastanza grande quindi le modifiche al database (un DB SQL di Azure se questo è importante) non sono particolarmente fattibili e dovrebbero essere evitate se possibile.C#: Cambia tipo di dati di recupero per Entity Framework

Il problema riguarda la colonna ID. Sfortunatamente, quando il sistema è stato creato, ci sono alcune tabelle che hanno un tipo di dati bigint e alcune che hanno un int - ma i modelli stessi provengono tutti da una classe base che ha un long per l'ID. Il precedente framework era in grado di gestire questa situazione, ma non sono stato in grado di trovare un modo per farlo con l'entity framework.

Di seguito è l'esempio più banale mi viene in mente:

public class Context : DbContext { 
    public IDbSet<Foo> Foos {get;set;} 
    public IDbSet<Bar> Bars {get;set;} 
} 
public abstract class BaseClass { 
    public long ID; 
} 
public class Foo : BaseClass { 
    ... 
} 
public class Bar : BaseClass { 
    ... 
} 
SQL Table: Foo 
+-------------+ 
| id : bigint | 
| ...   | 
+-------------+ 
SQL Table : Bar 
+-------------+ 
| id : int | 
| ...   | 
+-------------+ 

Quando provo a caricare un modello Bar, ottengo questo errore:

The 'ID' property on 'BaseClass' could not be set to a 'Int32' value. You must set this property to a non-null value of type 'Int64'. 

mi piacerebbe trovare un modo di dire al sistema che Bar ha inte, mentre Foo ha dei lunghi. Ho provato a sovrascrivere OnModelCreating nel contesto e definire HasColumnType per Bar. Che mi ha dato un nuovo errore:

Schema specified is not valid. Errors: 
    (105,12) : error 2019: Member Mapping specified is not valid. The type 'Edm.Int64[Nullable=False,DefaultValue=]' of member 'ID' in type 'Bar' is not compatible with 'SqlServer.int[Nullable=False,DefaultValue=,StoreGeneratedPattern=Identity]' of member 'ID' in type 'CodeFirstDatabaseSchema.Bar'. 

Mi sembra che se potessi solo cambiare il tipo di dati previsto per il ID di BaseClass per int prima di inviare la richiesta al server, allora dovrei essere in grado di up -convertare a long dopo aver ricevuto la risposta. Idealmente, mi piacerebbe farlo in base alle classi.

Qualcuno può indicarmi la giusta direzione?

risposta

4

Mentre è possibile eseguire il cast implicito di bigint to an int in SQL Server, sembra che i tipi EDM di Entity framework (che è davvero quello con cui si ha a che fare) non consentano una trasformazione implicita da un numero intero a 64 bit a un 32 bit tipo intero.

Questo è probabilmente per una buona ragione, perché si potrebbe facilmente traboccare e avere valori che non si adattano nei campi int.

Detto questo, dovresti avere due classi base, una per un ID int e una per un ID long. Non è bello, ma applica la logica che vuoi assolutamente; non sarà possibile memorizzare valori maggiori di quelli che possono essere contenuti in un int nel database, quindi perché dovresti essere in grado di farlo a livello di codice? Il framework Entity sta facendo la cosa giusta qui, non permettendoti di applicare questa trasformazione.

+0

Sì, questo era ciò di cui avevo paura. Riconosco che sto cercando di correggere un errore con un altro errore. Speravo solo di essere in grado di evitare importanti cambiamenti radicali con alcuni piccoli trucchi. Tutto quello che ho provato non funzionava, quindi penso di essermi rassegnato a fare esattamente quello che mi hai raccomandato. Se nessuna soluzione migliore arriva, la contrassegnerò come corretta. – Merwer

+0

@Merwer A volte, la verità fa male, per favore non sparare al messenger =) – casperOne

+0

Ciao @casperOne Scusate se mi intrometto con la mia domanda poiché è sullo stesso argomento. C'è un modo per fare il contrario. Ho una tabella con un id di tipo Int. Sta crescendo pericolosamente grande e mi chiedo se c'è un modo per cambiarlo in Long? (Entità Framwork CF 6.1) – hjavaher

Problemi correlati