Definire una relazione uno a uno con Linq To SQL
-
02-07-2019 - |
Domanda
Sto giocando con LinqToSQL usando un database multilingue esistente, ma sto riscontrando problemi nel mappare una relazione uno a uno abbastanza importante, quindi sospetto che sto usando la funzione in modo errato per la progettazione del mio database.
Supponi due tabelle, Category e CategoryDetail. Categoria contiene CategoryId (PK), ParentId e TemplateId. CategoryDetail contiene CategoryId (FK), LanguageId, Title and Description (nella lingua appropriata), con un PK combinato di CategoryId e LanguageId.
Se trascino queste tabelle nel designer LinqToSQL, il modello a oggetti risultante ha Categoria con una raccolta di oggetti CategoryDetail, che non dovrebbe mai essere il caso. Mi piacerebbe essere in grado di filtrare su LanguageId a livello di DataContext, il che significa che l'intera Categoria è incapsulata all'interno di Category.CategoryDetail, non tutte le versioni linguistiche incapsulate in Category.CategoryDetails.
Questo database ha funzionato bene sulla mia vecchia libreria di oggetti (un BOL e DAL personalizzati della vecchia scuola), ma temo che LinqToSQL richiederebbe che questo cambiasse per darmi il risultato richiesto.
Qual è il modo migliore per rendere questa relazione (e il filtraggio del linguaggio) il più semplice possibile?
Soluzione
È possibile visualizzare le proprietà dell'associazione. (Fare clic con il tasto destro sulla riga che rappresenta l'associazione e mostrare le proprietà.) Le proprietà ti diranno se si tratta di una relazione uno a uno o uno a molti. Ciò si riflette nel codice avendo una singola associazione di entità (uno-a-uno) o un'associazione di gruppi di entità (uno-a-molti).
Altri suggerimenti
Dovrei presumere che non possa essere un vero 1 a 1. Sembra che tu abbia un PK di CatID e Lang ID nella tabella Dettagli gatto. Ciò spiegherebbe perché sta mettendo una collezione. Potrei sbagliarmi perché non hai menzionato le PK della tabella CatDetails
EDIT: un Pk combinato di CatID e Lang ID fa sì che una relazione 1: m, e Linq a SQL stia effettivamente facendo la cosa giusta. L'unico modo in cui potrebbe essere un vero 1: 1 è se tu avessi anche un ID lang sul tavolo del gatto e questo faceva parte dell'FK. Penso che potrebbe essere necessario ripensare a ciò che si desidera fare o al modo in cui si desidera implementarlo.
Penso che LINQ to SQL modelli direttamente la struttura del database. Hai due tabelle in modo da creare 2 oggetti.
Se hai dato un'occhiata a LINQ to Entities questo ti permette di creare un altro livello sopra la struttura del database per creare classi più leggibili.
Poiché non hai una relazione 1: 1, la mappatura da sola non fornirà la funzionalità desiderata. Tuttavia, è facile fornire un metodo nella classe generata automaticamente padre che fa il lavoro:
public partial class Category
{
public IEnumerable<CategoryDetail> GetDetailsByLanguage(string langID)
{
return this.CategoryDetails.Where(c => c.LangID == langID);
}
}