Entity Framework: tabella senza chiave primaria

Ho un DB esistente con cui vorrei creare una nuova app usando EF4.0

Alcune tabelle non hanno le chiavi primarie definite in modo tale che quando creo un nuovo modello di dati di entity framework, ottengo il seguente messaggio: “La tabella / vista TABLE_NAME non ha una chiave primaria definita e nessuna chiave primaria valida può essere dedotta. la visualizzazione è stata esclusa. Per utilizzare l’ quadro, è necessario rivedere lo schema, aggiungere le chiavi corrette e decommentarlo “.

Se voglio usarli e modificare i dati, devo necessariamente aggiungere un PK a quelle tabelle, o c’è una soluzione alternativa in modo che non debba?

L’errore significa esattamente quello che dice.

Anche se potresti aggirare questo, fidati di me, non lo vuoi. Il numero di bug confusi che potrebbero essere introdotti è sconcertante e spaventoso, per non parlare del fatto che probabilmente le tue prestazioni andranno giù per le valvole.

Non aggirare questo. Risolvi il tuo modello di dati.

EDIT: Ho visto che un certo numero di persone sta facendo downvoting su questa domanda. Va bene, suppongo, ma tieni a mente che l’OP ha chiesto di mappare una tabella senza una chiave primaria, non una vista . La risposta è sempre la stessa. Lavorare attorno alla necessità di EF di avere un PK sulle tabelle è una ctriggers idea dal punto di vista della gestibilità, dell’integrità dei dati e delle prestazioni.

Alcuni hanno commentato che non hanno la possibilità di correggere il modello di dati sottostante perché stanno mappando su un’applicazione di terze parti. Non è una buona idea, dato che la modella può cambiare da sotto di te. Probabilmente, in tal caso, vorrai mappare a una vista, che, di nuovo, non è ciò che l’OP chiedeva.

Penso che questo sia risolto da Tillito:

Entity Framework e Vista SQL Server

Citerò la sua voce qui sotto:

Abbiamo avuto lo stesso problema e questa è la soluzione:

Per forzare il framework di quadro a utilizzare una colonna come chiave primaria, utilizzare ISNULL.

Per forzare il framework di quadro a non utilizzare una colonna come chiave primaria, utilizzare NULLIF.

Un modo semplice per applicarlo è quello di racchiudere l’istruzione select della tua vista in un’altra selezione.

Esempio:

SELECT ISNULL(MyPrimaryID,-999) MyPrimaryID, NULLIF(AnotherProperty,'') AnotherProperty FROM ( ... ) AS temp 

ha risposto 26 apr 10 alle 17:00 da Tillito

Le chiavi composite possono anche essere eseguite con Entity Framework Fluent API

 public class MyModelConfiguration : EntityTypeConfiguration { public MyModelConfiguration() { ToTable("MY_MODEL_TABLE"); HasKey(x => new { x.SourceId, x.StartDate, x.EndDate, x.GmsDate }); ... } } 

Nel mio caso ho dovuto mappare un’ quadro a una vista, che non aveva la chiave primaria. Inoltre, non mi è stato permesso di modificare questa vista. Fortunatamente, questa vista aveva una colonna che era una stringa unica. La mia soluzione era quella di contrassegnare questa colonna come chiave primaria:

 [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] [StringLength(255)] public string UserSID { get; set; } 

EF ingannato. Ha funzionato perfettamente, nessuno ha notato … 🙂

QUESTA SOLUZIONE FUNZIONA

Non è necessario eseguire la mapping manuale anche se non si dispone di un PK. Devi solo dire all’EF che una delle tue colonne è indice e la colonna indice non è annullabile.

Per fare ciò puoi aggiungere un numero di riga alla tua vista con isNull come la seguente

 select ISNULL(ROW_NUMBER() OVER (ORDER BY xxx), - 9999) AS id from a 

ISNULL(id, number) è il punto chiave qui perché dice all’EF che questa colonna può essere la chiave primaria

EF non richiede una chiave primaria nel database. In tal caso, non è ansible associare le quadro alle viste.

È ansible modificare l’SSDL (e il CSDL) per specificare un campo univoco come chiave primaria. Se non disponi di un campo unico, allora credo che tu sia protetto. Ma dovresti davvero avere un campo unico (e un PK), altrimenti avrai problemi in seguito.

Erick

Le risposte sopra sono corrette se davvero non hai un PK.

Ma se ce n’è uno, ma non è specificato con un indice nel DB, e non puoi cambiare il DB (sì, io lavoro nel mondo di Dilbert) puoi mappare manualmente i campi come chiave.

Avere una chiave di identity framework inutile è inutile a volte. Trovo se l’ID non viene utilizzato, perché aggiungerlo? Tuttavia, Entity non è così indulgente in proposito, quindi aggiungere un campo ID sarebbe il migliore. Anche nel caso in cui non venga utilizzato, è meglio che gestire gli incessivi errori di Entity sulla chiave di identity framework mancante.

Questa è solo un’aggiunta alla risposta di @Erick T. Se non esiste una singola colonna con valori univoci, la soluzione alternativa consiste nell’utilizzare una chiave composta, come indicato di seguito:

 [Key] [Column("LAST_NAME", Order = 1)] public string LastName { get; set; } [Key] [Column("FIRST_NAME", Order = 2)] public string FirstName { get; set; } 

Ancora una volta, questa è solo una soluzione. La vera soluzione è quella di correggere il modello di dati.

Se voglio usarli e modificare i dati, devo necessariamente aggiungere un PK a quelle tabelle, o c’è una soluzione alternativa in modo che non debba?

Per coloro che hanno raggiunto questa domanda e stanno utilizzando Entity Framework Core, non è più necessario aggiungere necessariamente un PK alle tabelle o eseguire una soluzione alternativa. Dal momento che EF Core 2.1 abbiamo una nuova funzione Tipi di query

I tipi di query devono essere utilizzati per:

  • Fornisce il tipo restituito per le query FromSql () ad hoc.
  • Mappatura alle viste del database.
  • Mappatura a tabelle che non hanno una chiave primaria definita.
  • Mappatura alle query definite nel modello.

Quindi nel tuo DbContext aggiungi semplicemente la seguente proprietà di tipo DbQuery invece di DbSet come sotto. Supponendo che il nome della tabella sia MyTable :

 public DbQuery MyTables { get; set; } 
  1. Modifica la struttura della tabella e aggiungi una colonna principale. Aggiorna il modello
  2. Modifica il file .EDMX nell’editor XML e prova ad aggiungere una nuova colonna sotto il tag per questa tabella specifica (NON FUNZIONERÀ)
  3. Invece di creare una nuova colonna Primaria in una tabella che esce, creerò una chiave composta coinvolgendo tutte le colonne esistenti ( LAVORATE )

Entity Framework: aggiunta di DataTable senza la chiave primaria al modello di entity framework.

Questo forse fino a tardi per rispondere … tuttavia …

Se un tavolo non ha una chiave primaria, ci sono alcuni scenari che devono essere analizzati per far funzionare correttamente l’EF. La regola è: EF funzionerà con tabelle / classi con chiave primaria. È così che traccia il monitoraggio …

Dì, la tua tabella 1. I record sono unici: l’unicità è costituita da una singola colonna di chiave esterna: 2. I record sono unici: l’unicità è costituita da una combinazione di più colonne. 3. I record non sono unici (per la maggior parte *).

Per gli scenari 1 e 2 è ansible aggiungere la seguente riga al modulo DbContext Metodo OnModelCreating: modelBuilder.Entity (). HasKey (x => new {x.column_a, x.column_b}); // tante colonne quante sono necessarie per rendere unici i record.

Per lo scenario n. 3 è ancora ansible utilizzare la soluzione di cui sopra (n. 1 + n. 2) dopo aver studiato la tabella (* ciò che rende comunque tutti i record unici). Se è necessario includere TUTTE le colonne per rendere tutti i record univoci, è ansible aggiungere una colonna di chiave primaria alla tabella. Se questa tabella proviene da un fornitore di terze parti che clonare questa tabella nel database locale (durante la notte o il tempo necessario) con la colonna chiave primaria aggiunta arbitraria tramite lo script clone.

Da un punto di vista pratico, ogni tabella – anche una tabella denormalizzata come una tabella di magazzino – dovrebbe avere una chiave primaria. Oppure, in caso contrario, dovrebbe avere almeno un indice univoco, non annullabile.

Senza una sorta di chiave univoca, i record duplicati possono apparire (e saranno) nella tabella, il che è molto problematico sia per i livelli ORM sia per la comprensione di base dei dati. Una tabella con record duplicati è probabilmente un sintomo di una ctriggers progettazione.

Per lo meno, la tabella dovrebbe avere almeno una colonna di id quadro. L’aggiunta di una colonna ID di generazione automatica richiede circa 2 minuti in SQL Server e 5 minuti in Oracle. Per quel ulteriore sforzo, molti, molti problemi saranno evitati.

Abbiamo riscontrato anche questo problema e, sebbene avessimo una colonna con valori null, l’importante era che avessimo una colonna dipendente che non aveva null e che la combinazione di queste due colonne era unica.

Quindi, per citare la risposta fornita da Pratap Reddy, ha funzionato bene per noi.

La tabella ha solo bisogno di avere una colonna che non consente null