UPDATE: Ultimamente ho ottenuto alcuni voti positivi, quindi ho pensato di far sapere alle persone che il consiglio che ho fornito di seguito non è il migliore. Dal momento che inizialmente avevo iniziato a fare mosse con Entity Framework su vecchi database keyless, ho capito che la cosa migliore che puoi fare in FAR è farlo per codice inverso.Ci sono alcuni buoni articoli là fuori su come farlo. Seguiteli e poi quando vuoi aggiungere una chiave, usa le annotazioni dei dati per "falsificare" la chiave.
Ad esempio, supponiamo che conosca la mia tabella Orders
, mentre non ha una chiave primaria, è garantito per avere sempre un solo numero di ordine per cliente. Dal momento che queste sono le prime due colonne sul tavolo, avevo impostare il codice prime classi di simile a questa:
[Key, Column(Order = 0)]
public Int32? OrderNumber { get; set; }
[Key, Column(Order = 1)]
public String Customer { get; set; }
In questo modo, si sta fondamentalmente finto EF a credere che ci sia una chiave cluster composto di OrderNumber e Customer. Questo ti permetterà di fare inserti, aggiornamenti, ecc. Sul tuo tavolo senza chiave.
Se non si ha familiarità con Reverse Code First, andare a trovare un buon tutorial su Entity Framework Code First. Poi vai a trovarne una su Reverse Code First (che sta facendo Code First con un database esistente). Quindi torna qui e guarda di nuovo il mio consiglio chiave. :)
risposta originale:
Primo: come altri hanno detto, l'opzione migliore è quella di aggiungere una chiave primaria alla tabella. Punto. Se puoi farlo, non leggere oltre.
Ma se non puoi, o semplicemente odi, c'è un modo per farlo senza la chiave primaria.
Nel mio caso, stavo lavorando con un sistema legacy (originariamente file flat su un AS400 portato su Access e quindi portato su T-SQL). Quindi ho dovuto trovare un modo. Questa è la mia soluzione. Quanto segue ha funzionato con me usando Entity Framework 6.0 (l'ultimo su NuGet al momento in cui scrivo).
Fare clic con il pulsante destro del mouse sul file .edmx in Esplora soluzioni. Scegliere "Apri con ..." e quindi selezionare "XML (Text) Editor". Qui stiamo modificando manualmente il codice generato automaticamente.
Cercare una linea come questa:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">
Rimuovere store:Name="table_name"
dalla fine.
Change store:Schema="whatever"
al Schema="whatever"
Osservi sotto quella linea e trovare il tag <DefiningQuery>
. Avrà una grande dichiarazione di selezione in esso. Rimuovi il tag e il suo contenuto.
Ora la linea dovrebbe essere simile a questo:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />
Abbiamo qualcos'altro da cambiare. Passare attraverso il file e trovare questo:
<EntityType Name="table_name">
Nelle vicinanze è probabilmente vedere qualche avvertimento del testo commentato che non aveva una chiave primaria ha identificato, in modo che il tasto è stato dedotto e la definizione è una lettura -solo tavolo/vista. Puoi lasciarlo o cancellarlo. L'ho cancellato.
Di seguito è il tag <Key>
. Questo è ciò che Entity Framework utilizzerà per inserire/aggiornare/eliminare. QUINDI ASSICURI DI FARE QUESTO DIRITTO.La proprietà (o le proprietà) in quel tag devono indicare una riga identificabile in modo univoco. Per esempio, diciamo che conosco la mia tabella orders
, mentre non ha una chiave primaria, è garantito per avere sempre un solo numero di ordine per cliente.
Così miniera assomiglia:
<EntityType Name="table_name">
<Key>
<PropertyRef Name="order_numbers" />
<PropertyRef Name="customer_name" />
</Key>
Scherzi a parte, non fare questo torto. Diciamo che anche se non dovrebbero mai esserci duplicati, in qualche modo due file entrano nel mio sistema con lo stesso numero di ordine e il nome del cliente. Whooops! Questo è quello che ottengo per non usare una chiave! Quindi io uso Entity Framework per eliminarne uno. Perché so che il duplicato è l'unico ordine messo in oggi, faccio questo:
var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today);
myModel.orders.Remove(duplicateOrder);
Indovinate un po? Ho appena cancellato sia il duplicato che l'originale! Questo perché ho detto a Entity Framework che order_number/cutomer_name era la mia chiave primaria. Così, quando ho detto che per rimuovere duplicateOrder, quello che ha fatto in sottofondo era qualcosa di simile:
DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)
E con questo avvertimento ... si dovrebbe ora essere pronti per partire!
Ho fatto un errore, non c'era una chiave primaria impostata sul tavolo, grazie per il vostro tempo! Ci scusiamo per l'inconveniente! – iKode
Mi è appena successo: probabilmente ho creato 1000 tabelle con chiavi primarie e ne ho dimenticato una, il messaggio di eccezione non aiuta molto la –
. davvero mi sono dimenticato di aggiungere la chiave primaria alla tabella. Proviamo a fare attenzione) – AEMLoviji