7

Esempio: diciamo che ho queste tre classi. Foo è un'entità Entity Framework corretta con un DbSet mentre voglio che il mio DbContext EF non sia a conoscenza di Bar e Baz perché ho contrassegnato la proprietà di Foo's Bar con il mio attributo SerializedColumn composto. Applicando tale attributo, voglio che EF serializzi l'istanza di Bar con i suoi Bazes in un singolo campo di stringa e deserializzi in modo trasparente un oggetto Bar quando un Foo viene materializzato da EF.Persistenza e recupero della proprietà di entità serializzata con il codice Entity Framework 6.1 prima

public class Foo 
{ 
    public Guid Id { get; set; } 
    [SerializedColumn] 
    public Bar Bar { get; set; } 
    // .. 
} 

public class Bar 
{ 
    public string Name { get; set; } 
    public Baz[] Baz { get; set; } 
    // .. 
} 

public class Baz 
{ 
    public string Name { get; set; } 
    // .. 
} 

Così colonne della tabella di Foo sarà simile:

[Id] [uniqueidentifier] NOT NULL 
[Bar] [nvarchar](max) NULL 

E quando interrogo un Foo ho tornare uno con la proprietà Bar già deserializzato. Quando inserisco o aggiorno una Foo la proprietà Bar viene serializzata da EF senza che io debba pensarci. L'unica cosa che devo fare è aggiungere l'attributo [SerializeColumn] alle proprietà.

Obiettivi:

  • Io non sono necessariamente in cerca di una soluzione soffiato completo (anche se avrei accettarlo), ma per una guida su dove fare un salto nel gasdotto di EF, e come farlo. OSSIA quali sono le classi EF, le configurazioni, le convenzioni, ecc. che devo tenere in considerazione?
  • Desidero che le migrazioni vengano generate come ci si aspetterebbe. Il che vuol dire che non vorrei che la mia proprietà Bar si trasformasse in un campo "Bar_Id" che punta a una tabella "Bar". Invece voglio un campo "Barra" nvarchar(max) che conterrà la versione serializzata di un oggetto Bar. Se questo semplicemente non è possibile, per favore dillo nella tua risposta.

Note:

  • L'idea è venuta dopo aver visto il video Building Applications with Entity Framework 6 da Rowan Miller.
  • ComplexType non soddisfa le mie esigenze. Ho bisogno di una serializzazione profonda e non ho bisogno di essere in grado di filtrare o ordinare su qualsiasi proprietà di ciò che è stato serializzato.
  • Ho in programma di serializzare con la libreria JSON di Newtonsoft, ma il modo in cui avviene la serializzazione non ha molta importanza.
+0

qualcosa di simile? http://stackoverflow.com/questions/14779740/can-i-embemb-an-object-in-an-ef-entity-serialize-on-save-deserialize-on-access – MutantNinjaCodeMonkey

+0

@MutantNinjaCodeMonkey L'ho fatto in il passato e funziona, ma sto cercando di rendere la persistenza totalmente trasparente. Questa è solo una proprietà 'Bar' con il mio composto' SerializeColumnAttribute', e nessuna proprietà 'BarSerialized'. –

+2

Abbastanza sicuro che questo non è possibile in EF6. Quello di cui hai veramente bisogno è un convertitore di tipo cliente.Questa funzione è [pianificata] (https://github.com/aspnet/EntityFramework/issues/242) per EF7 ma non ancora implementata. – DavidG

risposta

9

L'unica soluzione è questa,

public class Foo 
{ 
    public Guid Id { get; set; } 

    // Not Mapped attribute will make EF 
    // ignore this property completely 
    [NotMapped] 
    public Bar BarObject { 
     get; 
     set; 
    } 

    public string Bar{ 
     get{ 
      return JsonConvert.Serialize(BarObject); 
     } 
     set{ 
      BarObject = JsonConvert.Deserialize<BarObject>(value); 
     } 
    } 
} 

aggiornato come da suggerimento da @zds

+0

Grazie ad Akash, ma ho donato la bontà a @bubi dal momento che ha risposto per prima cosa con la stessa risposta, anche se un po 'meno dettagliata. Se potessi, avrei diviso la taglia tra entrambe le risposte. –

+1

Potrebbe essere meglio spostare la logica di serializzazione nella proprietà 'public string Bar'. Non serializzare e deserializzare tutto il tempo, quando si cambia qualcosa. O mi sta sfuggendo qualcosa? – zds

1

Non c'è modo di farlo senza modificare EF. Con EF 6 penso che diverse persone lo abbiano fatto con un campo di testo e alcune limitazioni (i bambini Bar e Bar non hanno accesso alla proprietà persistente EF o avete bisogno di altro lavoro dopo la deserializzazione).

+0

Sarei perfetto con le limitazioni fornite con un campo di testo nel database (nessun filtro, proiezioni nel database, ecc.). Oppure, per campo di testo, ti riferisci all'utilizzo di due proprietà, una contrassegnata [NotMapped] che è la versione in memoria, decifrata della proprietà crittografata che EF persisterà? –

+0

Per il campo di supporto, si intendono due proprietà, una contrassegnata [NotMapped] che è la versione in memoria, decrittografata della proprietà crittografata che EF persisterà. – bubi

+0

Bene, non c'è niente di sbagliato con le proprietà di supporto se questo è quello che viene. Grazie a @bubi, lascerò che questa generosità rimanga un po 'più a lungo per vedere se qualcun altro può aggiungere alcune informazioni utili. –

Problemi correlati