Come vengono generalmente gestite le tabelle composite quando non è disponibile uno strumento ORM?

3

Sto sviluppando un componente di Windows Runtime (C #) da utilizzare in un frontend HTML / JS per un'app di Windows Store. Ora, una delle richieste è di avere un database sul sistema locale per memorizzare i metadati relativi ai file che verranno scaricati. Dopo aver cercato ovunque ho iniziato a utilizzare SQLite combinato con la libreria wrapper sqlite-net .

Questa sembra essere ampiamente considerata l'opzione migliore, ma è una seccatura seria per me riuscire a lavorare. Forse il mio problema più grande è che non può mappare i tipi di raccolta alle tabelle composte. Questo mi ha portato a scrivere le mie query SQL per l'intera struttura del database, ma questa si è rivelata rapidamente una soluzione molto scomoda.

Per chiarire, questa è la situazione a cui mi riferisco:

class School {
    string Name { get; set; }
    List<Person> Students { get; set; }
}

class Person {
    int Id { get; set; }
    string Name { get; set; }
}

Per un esempio così piccolo potresti sicuramente scrivere le query SQL per le tre tabelle da solo, ma nella situazione attuale ho un oggetto che contiene diverse raccolte che a loro volta contengono anche collezioni di diversi livelli.

Forse sono viziato da Entity Framework ma è difficile credere che tutti utilizzino modelli di base che mantengano solo il (molto) limitato insieme di tipi supportati da sqlite-net o ognuno scriva il proprio wrapper attorno per tenere conto dei modelli con un po 'più di complessità.

In che modo queste situazioni vengono gestite in generale? Sto trascurando alcune soluzioni molto semplici?

    
posta Jeroen Vannevel 09.07.2014 - 19:13
fonte

2 risposte

4

Se non è disponibile ORM e la scrittura di tutti gli SQL manualmente diventa troppo noiosa, perché non scrivere un semplice generatore di codice SQL per le query? Questo è più semplice in quanto potrebbe sembrare a prima vista. Lo so per certo, dato che l'abbiamo fatto circa 10 anni fa, quando C # era nuovo e non c'era nessun ORM utilizzabile disponibile per .NET in quel momento.

Crea un assembly C # solo con le definizioni di classe "naked", allo scopo di fornire l'input rilevante per il tuo generatore di codice (quindi non devi creare alcun tipo di parser). Usa la riflessione per afferrare le informazioni da quell'assieme, per generare le definizioni di classe reali, incluso tutto il codice CRUD / SQL. Definisci alcuni attributi di classe per eventuali meta informazioni mancanti (ad esempio, sulle relazioni tra le tue classi e le tabelle composte necessarie). Può anche essere utile avere una convenzione coerente sulle chiavi tecniche primarie (ad esempio, lasciare che le chiavi primarie siano sempre della forma "class name" + ID ).

Dato che hai solo un modello di dati di medie dimensioni, devi solo supportare un elenco limitato di tipi di dati e puoi progettare il generatore di codice per seguire le convenzioni del tuo progetto. Questo è un po 'come scrivere il tuo ORM, ma con molto meno sforzo, dal momento che non deve funzionare per molti casi generali e diversi sistemi DB, solo per i casi maneggevoli del tuo progetto, e solo per SqLite-net.

    
risposta data 09.07.2014 - 21:04
fonte
0

Bene, gli elenchi di elenchi sono gestiti da più istruzioni select, quindi IDataReader.NextResult fornisce l'accesso alle selezioni successive. Quindi crea manualmente gli elenchi di elenchi.

Un altro modo per interpretare la domanda è come rappresentare un oggetto composito, e per quelle viste sono molto utili, ma sono di sola lettura, non possono inserire o aggiornare una vista.

Pseudocode inc, non citarlo.

sproc GetSchoolAndStudents(int schoolId) -- this is a stored procedure
{
    select ID, Name, Address, PhoneNumber, OtherSchoolData from School where ID = schoolId

    select ID, FirstName, LastName, DoB, Sex, HairColor, Grade from Student where SchoolID = schoolId
}

using(IDataReader reader = cmd.ExecuteReader())
{
    School school = null;
    while(reader.Read())
    {
         school = /* ADO.NET jazzhands */
    }
    if(reader.NextResult())
    {
        while(reader.Read())
        {
            school.Students.Add(new Student { /* ADO.NET jazzhands */ } );
        }
    }
}
    
risposta data 09.07.2014 - 19:29
fonte

Leggi altre domande sui tag