Ho una classe con un campo ExpandoObject per consentire agli utenti della mia classe di aggiungerne le proprietà.
public class Employee
{
public dynamic ExtendedProperties = new ExpandoObject();
public int Id { get; set; }
public string Name { get; set; }
}
Voglio mappare queste proprietà estese alle colonne nel database. Come posso salvare queste proprietà estese con Entity Framework Core 2.1?
Dovresti mappare questo in una colonna XML o JSON nel database e utilizzare una Conversione valore core EF.
Innanzitutto, Entity Framework Core non è stato progettato per tale comportamento. L'idea principale di EF Core (e anche di EF) è quella di mappare le colonne della tabella sulle proprietà della classe e viceversa. È necessario realizzare un corso di classe dinamico per ottenere ciò di cui hai bisogno.
Tuttavia, penso, possiamo implementare qualcosa come le proprietà dinamiche. Vedo due modi.
Modo 1:
Puoi creare una singola tabella con i campi Name
, Value
(e, forse, Type
) e memorizzare le tue proprietà al suo interno. È tua responsabilità archiviarli e selezionarli nelle operazioni CRUD.
Modo 2:
Il secondo approccio è più complicato ma anche più interessante. Assume la creazione di campi fisici nel database e, pertanto, può essere adatto se il database può essere utilizzato da altre applicazioni (incluse quelle legacy). Sto provando a implementare questo comportamento proprio ora in un mio progetto, ma il lavoro non è ancora finito e non conosco tutte le rocce sottomarine che attenderò davanti. Di cosa avrai bisogno.
1) Libreria EntityFramework.Triggers da @NickStrupat. Questa libreria offre la possibilità di lavorare con gli eventi durante le operazioni di inserimento / aggiornamento / cancellazione.
2) Una tabella FieldsDefinitions
- conterrà i metadati per tutte le proprietà aggiuntive. Questa tabella dovrebbe avere trigger per insert / delete, in cui verranno eseguiti i comandi SQL DDL per la modifica della struttura del database. La frase SQL verrà creata automaticamente in base ai dati del dizionario.
3) Qualcosa come Dictionary<FieldDefinition, string> CustomFields {get;set;}
nella classe Employee
.
4) Inserimento / aggiornamento di trigger per l'entità Employee
dovrebbe eseguire comandi DML per aggiornare i campi reali. La frase SQL verrà creata automaticamente in base ai dati del dizionario.
5) Ogni operazione di selezione dovrebbe aggiornare i campi personalizzati. Devo dirvi onestamente - può essere un collo di bottiglia quando si selezionano enormi quantità di dati, non ho ancora risolto questo problema.
PS
Mentre scrivevo questo post, è apparso la risposta di @DavidBrowne, e questa sembra essere la soluzione più elegante. Ma ho deciso di lasciare la mia risposta per vivere :) - può essere adatto a chi usa EF Core sotto 2.1 o EF.