2011-09-28 11 views
416

Sto utilizzando Entity Framework 1 con .net 3.5.Impossibile aggiornare EntitySet: poiché esiste un elemento DefiningQuery e nessun elemento <UpdateFunction> esiste

sto facendo qualcosa di semplice come questo:

var RoomDetails = context.Rooms.ToList(); 

foreach (var Room in Rooms) 
{   
    Room.LastUpdated = DateTime.Now; 
} 

sto ottenendo questo errore quando provo a fare:

context.SaveChanges(); 

ottengo l'errore:

Unable to update the EntitySet - because it has a DefiningQuery and no <UpdateFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.

I sto facendo molti aggiornamenti sul contesto e non ho problemi, è solo quando provo ad aggiornare questa particolare entità.

Tutte le mie ricerche mostrano la stessa cosa, che non c'è nessuna chiave primaria dichiarata sull'entità che sto tentando di aggiornare. Ma, ahimè, ho una chiave primaria dichiarata ...

+40

Ho fatto un errore, non c'era una chiave primaria impostata sul tavolo, grazie per il vostro tempo! Ci scusiamo per l'inconveniente! – iKode

+1

Mi è appena successo: probabilmente ho creato 1000 tabelle con chiavi primarie e ne ho dimenticato una, il messaggio di eccezione non aiuta molto la –

+1

. davvero mi sono dimenticato di aggiungere la chiave primaria alla tabella. Proviamo a fare attenzione) – AEMLoviji

risposta

822

Di solito succede perché uno dei seguenti motivi:

  • Entity Set è mappato alla vista Database
  • una query di database personalizzato
  • La tabella del database non ha una chiave primaria

Dopo averlo fatto, potrebbe essere ancora necessario aggiornare nel progettista di Entity Framework (o in alternativa eliminare l'entità e quindi aggiungerla) prima di in alto ottenendo l'errore.

+2

Assicurati di cambiare anche store: Schema a solo Schema per quel EntitySet, se hai ancora problemi. – Geoff

+0

Quindi, la soluzione è aggiungere una chiave primaria allora? –

+2

@DanielAllenLangdon: Sì. –

18

Ciò può verificarsi anche se il modello di dati non è aggiornato.

Speriamo che questo farà risparmiare qualcun altro frustrazione :)

71

Basta aggiungere una chiave primaria alla tabella. Questo è tutto. Problema risolto.

ALTER TABLE <TABLE_NAME> 
ADD CONSTRAINT <CONSTRAINT_NAME> PRIMARY KEY(<COLUMN_NAME>) 
+6

e non dimenticare di fare clic su "Aggiorna modello dal database" sul tuo file .edmx –

36

Basta notare che forse il tuo Entità avere chiave primaria ma vostra tabella nel database non ha chiave primaria.

6

Stavo ricevendo lo stesso messaggio di errore, ma nel mio scenario stavo cercando di aggiornare entità derivate da una relazione molti-a-molti usando un PJT (Pure Join Table).

Dalla lettura degli altri post, ho pensato di poterlo risolvere aggiungendo un campo PK aggiuntivo alla tabella di join ... Tuttavia, se aggiungi una colonna PK a una tabella di join, non è più un PJT e tu perdere tutti i vantaggi del framework di entità come la mappatura automatica delle relazioni tra le entità.

Quindi la soluzione nel mio caso era di modificare la tabella di join sul DB per creare un PK che includesse ENTRAMBE le colonne ID estranee.

+0

E 'così che la generazione di EDMX ha sempre funzionato? Sono abituato a lavorare con Code First che non richiede un PK su una tabella di join pura. –

26

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).

  1. 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.

  2. Cercare una linea come questa:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">

  3. Rimuovere store:Name="table_name" dalla fine.

  4. Change store:Schema="whatever" al Schema="whatever"

  5. Osservi sotto quella linea e trovare il tag <DefiningQuery>. Avrà una grande dichiarazione di selezione in esso. Rimuovi il tag e il suo contenuto.

  6. Ora la linea dovrebbe essere simile a questo:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

  7. Abbiamo qualcos'altro da cambiare. Passare attraverso il file e trovare questo:
    <EntityType Name="table_name">

  8. 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.

  9. 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!

+0

Trovato questa risposta dopo aver trovato la stessa soluzione al problema. Sicuramente la risposta corretta! Solo la definizione di una chiave primaria come menzionata in altre risposte non aiuterà in molti casi. –

3

così la sua vera, basta aggiungere una chiave primaria

Nota: essere sicuri che quando si sta aggiornando il diagramma EF dal database che si sta puntando al database destra, a mio caso la stringa di connessione stava puntando ad un DB locale invece del Dev DB aggiornato, errore di scolaro lo so, ma volevo postarlo perché può essere molto frustrante se sei convinto di aver aggiunto la chiave primaria e stai ancora ricevendo lo stesso errore

+0

Mi sento stupido - Collegamento DB errato –

1

Stavo ricevendo questo problema perché ero generare il mio EDMX da un database esistente (progettato da qualcun altro, e io uso il termine 'progettato' liberamente qui).

Risulta che il tavolo non aveva chiavi di sorta. EF stava generando il modello con molte chiavi multiple. Dovevo aggiungere una chiave primaria alla tabella db in SQL e poi aggiornare il mio modello in VS.

Questo lo ha risolto per me.

40

Questo è il caso per me. La semplice rimozione ha comportato un altro errore. Ho seguito i passaggi di questo post tranne l'ultimo. Per comodità, ho copiato i 4 passi dal post che ho seguito per risolvere il problema come segue:

  1. fare clic destro sul file edmx, selezionare Apri con, editor XML
  2. Individuare l'entità nel edmx : StorageModels elemento
  3. Rimuovere il DefiningQuery interamente
  4. Rinominare il store:Schema="dbo" a Schema="dbo" (in caso contrario, il codice genererà un errore dicendo che il nome non è valido)
+0

Grazie mille - questo è esattamente ciò che ha risolto il mio problema. È piuttosto inquietante che questo non sia stato corretto in EF. E, davvero incredibile, l'hai capito! –

+0

Ho provato a eliminare l'entità e ad aggiungerla di nuovo. Ricompilazione. Pulizia. Niente ha funzionato per me, tranne questo. – vintastic

+1

Questo ha risolto il mio problema ancora non so come hai trovato le risposte e perché il tuo suggerimento ha risolto il problema. –

4

si può verificare un errore, se la tua tabella non ha la chiave primaria, in questo caso la tabella è "sola lettura", e il comando db.SaveChanges() porterà sempre un errore

2

Ho avuto lo stesso problema. Come ha detto questo thread, la mia tabella non aveva un PK, quindi ho impostato il PK e ho eseguito il codice.Ma sfortunatamente l'errore è venuto di nuovo. Quello che ho fatto dopo è stato eliminare la connessione DB (eliminare il file .edmx nella cartella Modello di Solution Explorer) e ricrearlo. Errore passato dopo. Grazie a tutti per aver condiviso le vostre esperienze. Risparmia molto tempo.

0

L'aggiunta della chiave primaria ha funzionato anche per me!

Una volta fatto ciò, ecco come aggiornare il modello di dati senza eliminarlo -

Fare clic destro sulla pagina progettista edmx Entity e 'Aggiorna modello dal database'.

0

Ho avuto esattamente lo stesso problema, purtroppo aggiungendo la chiave primaria non risolvo il problema. Ecco come risolvo il mio:

  1. Assicurarsi di avere un primary key sul tavolo in modo da modificare la tabella e aggiungere una chiave primaria.
  2. Delete the ADO.NET Entity Data Model (file edmx) dove utilizzo per mappare e connettersi con il mio database.
  3. Add again a new file of ADO.NET Entity Data Model per connettersi con il mio database e per mappare le proprietà del mio modello.
  4. Clean and rebuild the solution.

Problema risolto.

0

Basta aggiungere una chiave primaria al vostro tavolo e quindi ricreare il vostro EF

0

ho dovuto rimuovere la tabella dal modello e aggiornare il modello portando di nuovo la tabella indietro. Immagino che la chiave primaria sia stata creata dopo che la tabella è stata inserita nel modello.

0

Impostare la chiave primaria, quindi salvare la tabella e l'aggiornamento, quindi andare su Model.edmx eliminare tabella e riprovare.

Problemi correlati