Attualmente sto lavorando con EF Core utilizzando una prima implementazione del database.
Tabelle attuali
Fizz
{
[Id] INT
[Category] varchar
[Value] varchar
}
Buzz
{
[Id] UniqueIdentifier
[TypeId1] INT
[TypeId2] INT
CONSTRAINT [FK_Buzz_Fizz_1] FOREIGN KEY ([TypeId1] REFERENCES [Fizz][Id])
CONSTRAINT [FK_Buzz_Fizz_2] FOREIGN KEY ([TypeId2] REFERENCES [Fizz][Id])
}
Fizz agisce attualmente su una tabella di ricerca. In questo modo è possibile utilizzare un singolo repository di dati per trovare valori diversi per categoria.
Buzz è una tabella che ha due valori di tipo diversi da memorizzare, ad esempio TypeId1 potrebbe essere una marca che esisterebbe in Fizz as (id, Brands, Nestle) e TypeId2 potrebbe essere un sapore che esisterebbe in Fizz come (id, Flavors, Grape) .
Ho impalcato il db per creare i modelli di dati. Quando si esegue l'applicazione, si verificano i seguenti eventi:
InvalidOperationException: impossibile determinare la relazione rappresentata dalla proprietà di navigazione "Buzz.TypeId1" di tipo "Fizz". Configurare manualmente la relazione o ignorare questa proprietà utilizzando l'attributo "[NotMapped]" o utilizzando "EntityTypeBuilder.Ignore" in "OnModelCreating".
Una soluzione che mi è venuta in mente è di rompere questa tabella di ricerca (Fizz) in più tabelle in modo che i riferimenti possano essere risolti non avendo i tipi duplicati usati per le chiavi esterne.
Ciò richiederebbe la rielaborazione della logica per l'attuale repository di dati per accedere a più tabelle o essere suddiviso in più repository di dati.
Un'altra soluzione potrebbe essere quella di modificare il DBContext generato e utilizzare DataAnnotations sul DataModel. Vorrei evitare di farlo poiché il contesto e i modelli verranno rigenerati in futuro e tali modifiche verranno sovrascritte.
C'è un modo per avere un datamodel generato da una tabella che ha più chiavi esterne su una singola tabella senza dover modificare il codice generato?
Per i posteri:
Con l'approccio al database, un impalcatura del db viene fatto per creare il contesto e i modelli di dati.
I modelli di dati generati (usando le tabelle di esempio sopra) assomigliano a questo:
public partial class Buzz
{
public Buzz()
{ }
public Guid Id { get; set; }
public int TypeId1 { get; set; }
public int TypeId2 { get; set; }
public Fizz TypeId1Fizz { get; set; }
public Fizz TypeId2Fizz { get; set; }
}
public partial class Fizz
{
public Fizz()
{ }
public int Id { get; set; }
public string Category { get; set; }
public string Value { get; set; }
public ICollection<Buzz> TypeId1Fizz { get; set; }
public ICollection<Buzz> TypeId2Fizz { get; set; }
}
Il problema è che la relazione in Buzz non può essere risolta.
Quando si utilizza lo scaffold sul database, tutti i modelli vengono generati come partial in una cartella specificata. Ho creato un partial per la classe Buzz in un'altra directory che risiede all'interno della directory creata dallo scaffold (assicurati che gli spazi dei nomi corrispondano a VS likes per aggiungere il nome della directory allo spazio dei nomi e che i partial non siano abbinati).
public partial class Buzz
{
[NotMapped]
public Fizz TypeId1Fizz { get; set; }
[NotMapped]
public Fizz TypeId2Fizz { get; set; }
}
ma Leustherin poi si perde la capacità di utilizzare. Includi per Fizz! EntityFramework non creerà un'istruzione di join SQL per te, quindi dovrai fare un viaggio extra nel DB per ottenere il tuo valore di ricerca!
Per aggirare questo problema, sostituire la funzione Get o GetAll del repository di dati e creare la propria istruzione di join.
Manutenibilità.
Ogni volta che i DataModel vengono rigenerati invece di ricevere un errore di runtime, ora c'è un errore di compilazione che ricorda allo sviluppatore di eliminare le proprietà extra dal modello di dati generato.
Non ci sono altre modifiche ai file generati automaticamente.
Non ci sono cambiamenti di schema importanti fatti per accogliere il cambiamento.
Farò del mio meglio per tenerlo aggiornato.