7

Sto implementando il database SQLite nella mia applicazione Windows Store (WinRT). Voglio relazione tra due tabelle (1: n) libro (1) - Capitolo (n)come creare la relazione collezione (1: n)

class Book 
{ 
    [SQLite.AutoIncrement, SQLite.PrimaryKey] 
    public int Id { get; set; } 
    public String Title { get; set; } 
    public String Description { get; set; } 
    public String Author { get; set; } 
    public List<Chapter> Chapters { get; set; } 

    public Book() 
    { 
     this.Chapeters = new List<Chapter>(); 
    } 
} 

ottengo

-  $exception {"Don't know about  System.Collections.Generic.List`1[Audioteka.Models.Chapter]"} System.Exception {System.NotSupportedException} 

+  [System.NotSupportedException] {"Don't know about System.Collections.Generic.List`1[Audioteka.Models.Chapter]"} System.NotSupportedException 

+  Data {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal} 
    HelpLink null string 
    HResult -2146233067 int 
+  InnerException null System.Exception 
    Message "Don't know about System.Collections.Generic.List`1[Audioteka.Models.Chapter]" string 

Che cosa sto facendo di sbagliato?

+0

c'è di più per il messaggio di errore? Un'eccezione, forse? –

+0

Questa informazione aggiuntiva è il messaggio dell'eccezione che ottengo – Fixus

+0

Non ho mai visto un messaggio di errore "Non so su System.Collections.Generic.List'1" prima. Sei sicuro di copiare e incollare l'esatto messaggio di errore? – Bobson

risposta

10

Solo per dare seguito al mio commento con un po 'di ricerca in più - SQLite-net non supporta nulla che non può essere direttamente mappato al database. Vedere here per il motivo:

L'ORM è in grado di prendere una definizione di classe .NET e convertirla in una definizione di tabella SQL. (La maggior parte degli ORM va nella direzione opposta.) Esegue ciò esaminando tutte le proprietà pubbliche delle classi ed è assistito da attributi che è possibile utilizzare per specificare i dettagli della colonna.

Si può considerare di usare un diverso ORM effettivamente accedere ai dati (io uso Vici Coolstorage), se è questo che stai cercando di fare, o è sufficiente rimuovere il List<Chapters> dalla classe e aggiungere un campo BookID al Chapters classe. Ecco come il database lo rappresenterebbe.

Ai fini di lavorare con esso, si potrebbe aggiungere uno di questi per classe:

List<Chapters> Chapters { 
    get { 
    return db.Query<Chapters> ("select * from Chapters where BookId = ?", this.Id); 
    } 
} 

o

List<Chapters> Chapters { 
    get { 
    return db.Query<Chapters>.Where(b => b.BookId == this.Id); 
    } 
} 

che avrebbe almeno lasciare che si tira la lista con facilità, anche se sarebbe essere lento perché colpisce il database ogni volta che lo si accede.

+0

ok ma ho bisogno della collezione di capitoli nel mio oggetto Libro :) Vedo che dovrei ignorare i capitoli per ORM e popolarlo manualmente mentre raccolgo l'oggetto. Hmm è un grande svantaggio di SQLite:/ – Fixus

+0

@Fixus - SQLite-net non è probabilmente l'ORM che si desidera utilizzare. Sembra essere strettamente per la creazione e la popolazione del database, con le funzionalità di query come un ripensamento. SQLite non ha i problemi, ma è necessario un modo diverso per comunicare con esso. – Bobson

+0

@Fixus - Ho anche aggiunto un modo per popolare 'Chapters', sebbene non sia un ottimo modo per gestirlo. – Bobson

9

Dai uno sguardo allo SQLite-Net Extensions. Fornisce relazioni complesse su SQLite-Net utilizzando la reflection.

Esempio estratto dal sito:

public class Stock 
{ 
    [PrimaryKey, AutoIncrement] 
    public int Id { get; set; } 
    [MaxLength(8)] 
    public string Symbol { get; set; } 

    [OneToMany]  // One to many relationship with Valuation 
    public List<Valuation> Valuations { get; set; } 
} 

public class Valuation 
{ 
    [PrimaryKey, AutoIncrement] 
    public int Id { get; set; } 

    [ForeignKey(typeof(Stock))]  // Specify the foreign key 
    public int StockId { get; set; } 
    public DateTime Time { get; set; } 
    public decimal Price { get; set; } 

    [ManyToOne]  // Many to one relationship with Stock 
    public Stock Stock { get; set; } 
}