Domanda

Ho un problema l'aggiornamento di una chiave esterna in un'entità Entity Framework. Sto usando entità auto tracking e ho un'entità con alcuni rapporti in cui la chiave esterna è presente come una proprietà (una delle nuove caratteristiche di EF4) anche. La chiave (un intero) è contrassegnato come modalità Null e concorrenza fisso.

In particolare ho un'entità di allarme con una relazione molti a 0..1 relazione a un utente conferma. (Un utente può confermare diversi allarmi, ma un allarme può essere confermata solo da zero o uno degli utenti).

Le definizioni di entità (semplificato):

Alarm properties
Id      Int32   non-nullable  identity entity key
UserId  Int32   nullable concurrency mode fixed
Alarm navigation properties
User    0..1 multiplicity

User properties
Id      Int32   non-nullable  identity entity key
Name    String  non-nullable

Nel mio un'entità autonoma di monitoraggio l'utente conferma id è generato automaticamente come Nullable proprio come previsto, se assegno un utente a un allarme già persistente e ApplyChanges correre, i tentativi di estensione di sé contesto di tracciamento per impostare il valore originale ( null) nel contesto EF (in ImpostaValore nelle estensioni contesto), ma salta silenziosamente che, poiché il ClrEquivalentType del EdmType è un Int32 non annullabile.

estensione

Auto-generated:

    private static void SetValue(this OriginalValueRecord record, EdmProperty edmProperty, object value)
    {
        if (value == null)
        {
            Type entityClrType = ((PrimitiveType)edmProperty.TypeUsage.EdmType).ClrEquivalentType;
            if (entityClrType.IsValueType &&
                !(entityClrType.IsGenericType && typeof(Nullable<>) == entityClrType.GetGenericTypeDefinition()))
            {
                // Skip setting null original values on non-nullable CLR types because the ObjectStateEntry won't allow this
                return;
            }
        }

        int ordinal = record.GetOrdinal(edmProperty.Name);
        record.SetValue(ordinal, value);
    }

Quando l'EF poi tenta di aggiornare il mio allarme ottengo un OptimisticConcurrencyException perché costruisce una clausola WHERE nell'istruzione UPDATE dove utilizza 0 (zero) come l'utente originale valore di chiave esterna invece del corretto "è nullo". (La clausola WHERE è parte del meccanismo EF ottimistica concorrenza, dove i valori originali delle proprietà contrassegnati con modalità concorrenza "fisso" sono controllate agains le proprietà nel database).

sono le chiavi straniere Null / tipi primitivi non sono pienamente supportati in entità di auto monitoraggio per EF? In caso contrario, io sono costretto a usare le entità fittizie, invece di nulla o ci sono altre soluzioni?

Aggiorna Ho cercato di riprodurre il problema senza STE, ma EF pianura sembra gestire bene la concorrenza ottimistica per le chiavi esterne nullable, quindi questo è un problema di STE, non un problema di EF. C'è numerose questioni con enti indipendenti di monitoraggio, quindi non è sorprendente che ci sia un problema tecnico qui. Se trovo una soluzione che può essere implementato nello script STE T4 mi post qui.

È stato utile?

Soluzione

Bill Huth ha postato una patch lavora a MSDN .

Altri suggerimenti

Sì, chiavi esterne nullable sono certamente consentiti. Noi li usiamo tutto il luogo. Non si mostra il database o il modello, quindi è difficile essere certi che cosa il problema potrebbe essere, ma suona come se Entity Framework non riesce a capire la chiave primaria di una delle tabelle coinvolte. Forse non si dispone di uno, forse perché uno di loro è una vista? Sto indovinando qui, perché non si danno molte informazioni su quello che stai facendo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top