Entity Framework e SQL Server

Per vari motivi che non ho la libertà di parlare, ci sono la definizione di una vista sul nostro database di Sql Server 2005 in questo modo:

CREATE VIEW [dbo].[MeterProvingStatisticsPoint]
AS
SELECT
    CAST(0 AS BIGINT) AS 'RowNumber',
    CAST(0 AS BIGINT) AS 'ProverTicketId',
    CAST(0 AS INT) AS 'ReportNumber',
    GETDATE() AS 'CompletedDateTime',
    CAST(1.1 AS float) AS 'MeterFactor',
    CAST(1.1 AS float) AS 'Density',
    CAST(1.1 AS float) AS 'FlowRate',
    CAST(1.1 AS float) AS 'Average',
    CAST(1.1 AS float) AS 'StandardDeviation',
    CAST(1.1 AS float) AS 'MeanPlus2XStandardDeviation',
    CAST(1.1 AS float) AS 'MeanMinus2XStandardDeviation'
WHERE 0 = 1

L’idea è che l’Entity Framework si crea un’entità basata su query, che viene, ma genera un errore che indica le operazioni seguenti:

Avviso 6002: La tabella/vista ‘Keystone_Local.dbo.MeterProvingStatisticsPoint’ non hanno definita una chiave primaria. La chiave è stata dedotta e la definizione è stata creata come sola tabella/vista.

E decide che il CompletedDateTime campo sarà questa entità chiave primaria.

Stiamo usando EdmGen per generare il modello. C’è un modo per non avere entity framework includere qualsiasi campo di questa visione, come una chiave primaria?

InformationsquelleAutor Sergio Romero | 2009-06-18



9 Replies
  1. 237

    Abbiamo avuto lo stesso problema e questa è la soluzione:

    Per forza di entity framework utilizzare una colonna come chiave primaria, utilizzare ISNULL.

    Per forza di entity framework di non utilizzare una colonna come chiave primaria, utilizzare NULLIF.

    Un modo semplice per applicare questo è quello di avvolgere l’istruzione select del vostro punto di vista in un’altra select.

    Esempio:

    SELECT
      ISNULL(MyPrimaryID,-999) MyPrimaryID,
      NULLIF(AnotherProperty,'') AnotherProperty
      FROM ( ... ) AS temp
    • Credo che questo sia il migliore auspicabile. Linea di fondo funziona.
    • Ho provato e non funziona. Non EF designer analizza la definizione della vista o solo deduce le colonne da i risultati dei dati?
    • Grazie! Ha funzionato perfettamente. @sabanito penso che analizza la definizione. che è il motivo per cui è necessario in particolare avvolgere il tasto proprietà in IsNull(). Ho una vista che non restituisce null (e non può restituire null), ma a causa del modo in cui la logica è stato scritto, EF non in grado di determinare che era il caso fino a quando ho avvolto le chiavi in IsNull().
    • Ha funzionato per me. Utilizza la SchemaDefinition vista.
    • L’unico problema che vedo qui è che vista si potrebbe legittimamente necessario restituire una stringa vuota “. Quello che ho fatto, è stato semplicemente gettato la colonna per il suo proprio tipo di dati. per esempio, se AnotherProperty avuto un tipo di dati varchar(50) vorrei lanciarla in quanto tale ” CONVERT(VARCHAR(50), AnotherProperty) COME [AnotherProperty]’. questo mascherato il supporto di valori null da EF e anche permesso stringhe vuote.
    • sì, questo funziona ad esempio per rendere EF utilizzare la colonna come chiave primaria isnull(CONVERT(VARCHAR(50), newid ()),””) COME [PK]
    • A parte non essere solo un fastidioso messaggio nella soluzione, che male c’è a non risolvere i problemi di questo? Concordo con la tua soluzione, ma francamente non mi sento che io debba fare questo – penso che siamo tutti d’accordo che questo è un bug giusto?
    • Questo è ancora attuale ? Ho ancora il messaggio di avviso dopo l’aggiornamento del modello di Entità, anche utilizzando ISNULL nei miei punti di vista. Visual Studio 2012 .NET Framework 4.5, MSSQL Server 2012.
    • Non funziona per me, io.e ho ancora l’errore, con EF 6, VS 2013, .NET 4.5, SQL Server 2012
    • Ho il sospetto che la soluzione di cui sopra sarà ancora produrre l’avviso, ma potrebbe essere una soluzione valida per EF essere troppo avidi e un numero di colonne non chiave come Chiave Primaria, che è il comportamento che stiamo vedendo (e dover correggere manualmente).
    • Abbiamo ottenuto questo lavoro ora; è necessario riavviare VS2013 per l’errore di andare via però.. molto fastidioso
    • Anzi, ho cercato una soluzione per ore, e alla fine ho dovuto riavviare VS2012. Io modificare la risposta di includere questo.
    • Perché non impostare tutti la vista di entità campi di proprietà di “Chiave di Entità = True” in edmx designer invece di aggiungere ISNULL/NULLIF di codice SQL? Sembra una performance migliore soluzione approccio. Non riuscivo a trovare difetti.
    • Ciao, questo problema è stato risolto nell’ultima EF?
    • Qualcuno qui a lavorare con Oracle? Non è possibile ottenere la entità lavorare
    • L’altra opzione è quella di definire una chiave primaria univoca utilizzando FluentAPI – utilizzo dei campi in oggetto; ` generatore.Entità<DailyTick>() .ToTable(“vwDailyTick”) .HasKey(“CurrencyPairId”, “OpenTickId”);`

  2. 65

    Sono stato in grado di risolvere questo problema utilizzando la finestra di progettazione.

    1. Aprire il Browser Modello.
    2. Trovare la visualizzazione del diagramma.
    3. Fare clic destro sulla chiave primaria, e assicurarsi che “Chiave di Entità” è selezionata.
    4. Multi-selezionare tutti i non-chiavi primarie. Utilizzare i tasti Ctrl o Maiusc.
    5. Nella finestra Proprietà (premere F4 se necessaria), modificare il
      “Chiave di entità” a discesa per Falso.
    6. Salvare le modifiche.
    7. Chiudere Visual Studio e ri-aprirlo. Sto usando Visual Studio 2013 con EF 6
      e ho dovuto fare questo per ottenere gli avvisi di andare via.

    Non ho dovuto cambiare il mio punto di vista per utilizzare la funzione ISNULL, NULLIF, o FONDERSI soluzioni alternative. Se si aggiorna il modello del database, le avvertenze apparirà nuovamente, ma andrà via se chiudi e riapri VS. Le modifiche apportate nella finestra di progettazione saranno conservati e non interessati dall’aggiornamento.

    • Confermato. È necessario riavviare VS2013 per rendere l’avviso di andare via.
    • “Hai provato a spegnerlo e riaccenderlo?” 😉 Grazie, funziona come un fascino!
    • Nuova generazione coder utilizzare questo come soluzione 🙂 🙂
    • Quando sto creando vista, non hanno nemmeno arrivare a essere il diagramma del modello. Sono commentati nel file xml
    • Semplice e di facile soluzione e non sembrare molto di un nono hacky fix come la manipolazione della vista! Grazie.
    • Confermato VS2017 deve essere riavviato anche per l’avviso di andare via.
    • Ha funzionato per me, ma ho combinato con ISNULL(MyPrimaryID,-1), come MyPrimaryID.

  3. 45

    D’accordo con @Tillito, tuttavia, nella maggior parte dei casi si tratta di fallo SQL optimizer e non utilizzare indici.

    Può essere ovvio per qualcuno, ma ho bruciato ore a risolvere i problemi di prestazioni utilizzo di Tillito soluzione. Diciamo che la tabella:

     Create table OrderDetail
        (  
           Id int primary key,
           CustomerId int references Customer(Id),
           Amount decimal default(0)
        );
     Create index ix_customer on OrderDetail(CustomerId);

    e la vista è qualcosa di simile a questo

     Create view CustomerView
        As
          Select 
              IsNull(CustomerId, -1) as CustomerId, -- forcing EF to use it as key
              Sum(Amount) as Amount
          From OrderDetail
          Group by CustomerId

    Sql optimizer non utilizzare l’indice ix_customer e eseguire la scansione della tabella primaria, indice, ma se invece di:

    Group by CustomerId

    si utilizza

    Group by IsNull(CustomerId, -1)

    farà MS SQL (almeno 2008) includono l’indice destro in piano.

    Se

    • Questo dovrebbe essere un commento su Tillito risposta, non una risposta di per sé, in quanto non fornisce una soluzione per le OP domanda.
    • Il ragazzo ha un rep di 1, non può aggiungere un commento, di sicurezza.
    • Non c’è modo che possa adattarsi a tutte queste informazioni in un commento, ha più senso avere una risposta separato.
    • Questa risposta è stata modificata sei giorni dopo che è stato inviato e ho postato il mio commento. Vedere la cronologia delle revisioni.
  4. 8

    Questo metodo funziona bene per me. Io uso la funzione ISNULL() per il campo chiave primaria, e COALESCE() se il campo non deve essere la chiave primaria, ma dovrebbe avere anche un non-valore nullable. Questo esempio produce il campo ID con un non nullable chiave primaria. Gli altri campi non sono le chiavi, e sono (Nessuno) come attributo Nullable.

    SELECT      
    ISNULL(P.ID, - 1) AS ID,  
    COALESCE (P.PurchaseAgent, U.[User Nickname]) AS PurchaseAgent,  
    COALESCE (P.PurchaseAuthority, 0) AS PurchaseAuthority,  
    COALESCE (P.AgencyCode, '') AS AgencyCode,  
    COALESCE (P.UserID, U.ID) AS UserID,  
    COALESCE (P.AssignPOs, 'false') AS AssignPOs,  
    COALESCE (P.AuthString, '') AS AuthString,  
    COALESCE (P.AssignVendors, 'false') AS AssignVendors 
    FROM Users AS U  
    INNER JOIN Users AS AU ON U.Login = AU.UserName  
    LEFT OUTER JOIN PurchaseAgents AS P ON U.ID = P.UserID

    se davvero non si dispone di una chiave primaria, è in grado di imitare uno utilizzando ROW_NUMBER per generare una pseudo-chiave che viene ignorato dal tuo codice. Per esempio:

    SELECT
    ROW_NUMBER() OVER(ORDER BY A,B) AS Id,
    A, B
    FROM SOMETABLE
    • Sì, ho finito per barare con NEWID() as id, ma è la stessa idea. E ci sono legittimi casi d’uso — se avete una visualizzazione in sola lettura, per esempio. Brutto, EF, brutto.
  5. 4

    Corrente Entity Framework EDM generatore di creare una chiave composta da tutti non nullable campi nella visualizzazione. Al fine di ottenere il controllo su questo, sarà necessario modificare la visualizzazione e la sottostante tabella impostazione di colonne le colonne di nullable quando non si desidera loro di essere parte della chiave primaria. Il contrario è anche vero, come ho rilevato, l’EDM chiave generata stava causando problemi di duplicazione dei dati, ho avuto modo di definire una colonna nullable come non annullabili per forza composito chiave EDM per includere tale colonna.

    • Abbiamo lo stesso problema con il derivato PK, l’entità restituisce i record duplicati ed è completamente fastidioso. Se si esegue Context.Entity.ToList() record duplicati, ma se si esegue la Query SQL generato da EF direttamente (ottenuto con LINQPad), senza registrare la duplicazione avviene. Sembra essere un problema di mappatura i record del database a oggetti entità (POCO) restituito, come il PK è dedotto mediante spiegato la logica (non nullable colonne).
  6. 3

    Sembra che è un problema noto con EdmGen: http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/12aaac4d-2be8-44f3-9448-d7c659585945/

    • Che senso. Così, c’è un modo per definire una colonna not null null o in vista il modo in cui siamo definizione?
    • Scusate, mi sono già oltre il mio livello di competenza in Entity Framework. 🙂
    • Chiunque sa quando questo problema sarà risolto? Fastidioso dover risolvere questo quando si hanno non nulla, le colonne che non sono chiavi primarie.
  7. 3

    Per ottenere una vista ho dovuto mostrare solo uno colonna di chiave primaria ho creato una seconda vista che ha sottolineato il primo e utilizzato NULLIF per rendere i tipi nullable. Questo ha funzionato per me per rendere l’EF credo che ci sia stato un solo chiave primaria della vista.

    Non sono sicuro se questo vi aiuterà se dal momento che non credo che gli EF accettare un entità SENZA chiave primaria.

  8. 2

    Se non si vuole pasticciare con quello che dovrebbe essere la chiave primaria, mi raccomando:

    1. Incorporare ROW_NUMBER nella vostra selezione
    2. Impostare come chiave primaria
    3. Impostare tutte le altre colonne/soci non primario nel modello
  9. 1

    A causa di problemi di cui sopra, preferisco tabella funzioni di valore.

    Se si dispone di questo:

    CREATE VIEW [dbo].[MyView] AS SELECT A, B FROM dbo.Something

    creare questo:

    CREATE FUNCTION MyFunction() RETURNS TABLE AS RETURN (SELECT * FROM [dbo].[MyView])

    Poi basta importare la funzione piuttosto che la vista.

    • Come creare associazioni tra le entità, andando con questo approccio? È possibile?

Lascia un commento