Pietosamente, no, non puoi farlo. ComplexType sembra promettente e sembra essere un bel "gruppo di colonne", ma il team EF lo ha semplicemente progettato per un uso completamente diverso e moltissime funzionalità legate al suo utilizzo come "gruppo di colonne" sono semplicemente mancanti.
Per quanto riguarda la mia conoscenza, "Ovviamente potrei fare quanto segue" è l'unico modo possibile. Devi solo definire il raggruppamento in base a una sottocolonna o una proiezione ad un tipo che il database saprà come confrontare.
Il problema principale è che la squadra EF vede il ComplexType non come un gruppo di colonne che consentono di riordinare il vostro entità con molti campi, ma, per loro, è un altro tipo di entità, tipo di uno transitorio. Il ComplexType è pensato per rappresentare oggetti che vengono restituiti per esempio da una stored procedure (o funzioni di ritorno della tabella) che restituisce un set di risultati di 5 colonne che non possono essere mappate su una tabella/classe esistente normale. Ad esempio, immagina di avere una tabella/classe Cliente che contiene 50 colonne/campi, la maggior parte di essi non null e che rappresentano alcuni dati sensibili. Si crea una stored procedure che prende un ID del cliente e restituisce il suo {nome, indirizzo, telefono di contatto, misura della scarpa}. Ovviamente, se si impostano tali risultati ritagliati, non è possibile decodificarli/mapparli alla classe Customer che ha tonnellate di campi che non possono essere nulli. Quindi, come rappresenti il risultato in EF?
Prima opzione, piuttosto zoppa, è semplicemente ignorare EF e parlare direttamente al database e leggere/tradurre/decomprimere le righe/colonne a mano. Bene, conosciamo SqlClient, possiamo farlo.
La seconda opzione, brutta, consiste nel definire in EF una tabella/vista di stub, ad esempio CustomerView, che conterrà solo le colonne {nome, indirizzo, numero di telefono, numero di scarpe} e mappare il set di risultati della stored procedure ad esso. Funzionerebbe bene, ma se per caso 'generate database' formate il modello EF, otterrete anche quella tabella inutilizzata in più ..
Terza opzione per il salvataggio sono ComplexType. Invece di provare a creare una tabella o una vista shadow, devi solo dire all'EF che "c'è un tipo di dati extra" che non verrà mai mappato alla sua tabella e che non avrà mai definito un PrimaryKey e che l'EF per comodità, mappalo in una classe come qualsiasi altro oggetto dati. Ora, avendo questo tipo, è possibile restituirlo dalle procedure e recuperarlo come un oggetto ben digitato, è possibile passarlo come parametro della procedura, ecc. Ma: non è possibile mantenerlo da solo. Non ha una propria mappatura delle tabelle e nessuna propria chiave primaria.Ha nessuna identità.
È bello, ma bene, perché si desidera che tale tipo di dati venga restituito da una procedura? Probabilmente, la procedura ha elaborato o generato alcuni dati e si desidera che li memorizzi in alcune tabelle. Non hai definito un'entità intera normale, quindi quella cosa è solo un 'pacchetto dati', quindi probabilmente scriverai quel valore risultante su quella tabella insieme ad altri dati. Ed è per questo che l'EF ti permette di mappare ComplexType ad alcune colonne di una tabella: se hai ottenuto quell'oggetto risultato temporaneo da una procedura e ora vuoi scriverlo da qualche parte, non devi farlo manualmente colonna per colonna , basta mapparlo alle colonne "nome, indirizzo, telefono di contatto, dimensione della scarpa" del cliente.
Il punto più importante è che il server di database non conosce mai tale ComplexType esistente. Come ho detto, non aveva identità. Quando si tenta di fare una query LINQ come
aset.Where(item => item.complexProperty == complexValue)
allora, il complexValue è un oggetto CLR che non è mappata a qualsiasi tavolo, non ha identità, quindi NO PK, quindi EF ha completamente idea di come controllare se l '"oggetto della mano sinistra" è lo stesso di "oggetto della mano destra". Se gli oggetti avessero definito un'identità, potrebbe controllare PK sul lato server, o fare un confronto di oggetti di riferimento sul lato client, ma qui - semplicemente fallisce.
Sono assolutamente d'accordo sul fatto che questa è un'altra caratteristica dannatamente utile nell'EF che manca. Credo che sarebbe estremamente facile per il team EF confrontare i ComplexTypes su base colonna per colonna, ma non è così. Semplicemente non pensavano che ComplexTypes potesse essere usato per mettere in ordine i tavoli. Hanno significato che fosse un pacchetto di dati temporaneo da passare a e da stored procedure e funzioni .. Peccato.
La parte 'MyObject' del modello EF? Posso fare una cosa simile con una proprietà di navigazione su 'MyObject' (dove MyObject: Item is n: 1). L'SQL generato è orribile, ma almeno funziona. –
In realtà è un ComplexType. Quindi, in breve sì, EF è a conoscenza del tipo di oggetto. Poiché tutte le proprietà esistono effettivamente sulla stessa tabella, mi aspetto che l'SQL risultante sia molto più pulito di se stesse usando una proprietà di navigazione (se potessi farlo funzionare ovviamente!) – mindlessgoods