2014-12-17 17 views
11

Ho letto un sacco di domande sullo stesso errore ma nessuna da quando corrisponde al mio problema esatto. Sto cercando di accedere alla proprietà di un oggetto, a sua volta parte di un oggetto radice, utilizzando Fluent NHibernate. Alcune risposte dicono che devo usare le proiezioni, altre che devo usare join e penso che dovrebbe funzionare con il caricamento lento.NHibernate fluente "Impossibile risolvere la proprietà"

Ecco le mie due classi insieme con le mappature Fluent:

classe Artista

classe
public class Artist 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual IList<Album> Albums { get; set; } 
    public virtual string MusicBrainzId { get; set; } 
    public virtual string TheAudioDbId { get; set; } 

    public Artist() { } 
} 

public class ArtistMap : ClassMap<Artist> 
{ 
    public ArtistMap() 
    { 
     LazyLoad(); 
     Id(a => a.Id); 
     Map(a => a.Name).Index("Name"); 
     HasMany(a => a.Albums) 
      .Cascade.All(); 
     Map(a => a.MusicBrainzId); 
     Map(a => a.TheAudioDbId); 
    } 
} 

Album

public class Album 
{ 
    public virtual int Id { get; set; } 
    public virtual Artist Artist { get; set; } 
    public virtual string Name { get; set; } 
    public virtual IList<Track> Tracks { get; set; } 
    public virtual DateTime ReleaseDate { get; set; } 
    public virtual string TheAudioDbId { get; set; } 
    public virtual string MusicBrainzId { get; set; } 

    public Album() { } 
} 

public class AlbumMap : ClassMap<Album> 
{ 
    public AlbumMap() 
    { 
     LazyLoad(); 
     Id(a => a.Id); 
     References(a => a.Artist) 
      .Cascade.All(); 
     Map(a => a.Name).Index("Name"); 
     HasMany(a => a.Tracks) 
      .Cascade.All(); 
     Map(a => a.ReleaseDate); 
     Map(a => a.TheAudioDbId); 
     Map(a => a.MusicBrainzId); 
    } 
} 

e l'errore si verifica quando questo codice viene interpretato :

var riAlbum = session.QueryOver<Album>() 
       .Where(x => x.Name == albumName && x.Artist.Name == artist) 
       .List().FirstOrDefault(); 

L'errore si verifica quando Fluent NHibernate tenta di risolvere il valore x.Artist.Name:

{ "non potrebbe risolvere proprietà: Artist.Name di: Album"}

Cosa sarebbe il modo corretto di farlo?

risposta

19

È necessario pensare alla query QueryOver come (quasi) direttamente la traduzione in SQL. Con questo in mente, immaginare questa query SQL:

select 
    Album.* 
from 
    Album 
where 
    Album.Name = 'SomeAlbumName' and 
    Album.Artist.Name = 'SomeArtistName' 

Questo non funziona perché non è possibile accedere alle proprietà di una tabella correlata come quella in un'istruzione SQL. È necessario creare un join Album-Artist e quindi utilizzare una clausola Where:

var riAlbum = 
    session.QueryOver<Album>() 
       .Where(al => al.Name == albumName) 
      .JoinQueryOver(al => al.Artist) 
       .Where(ar => ar.Name == artistName) 
      .List() 
      .FirstOrDefault(); 

Inoltre, dal momento che si sta utilizzando FirstOrDefault, si può prendere in considerazione lo spostamento che la logica alla fine del database. Attualmente, stai ritirando ogni record corrispondente ai tuoi criteri e poi prendi il primo. È possibile utilizzare .Take per limitare la query al risultato 1:

var riAlbum = 
    session.QueryOver<Album>() 
       .Where(al => al.Name == albumName) 
      .JoinQueryOver(al => al.Artist) 
       .Where(ar => ar.Name == artistName) 
      .Take(1) 
      .SingleOrDefault<Album>(); 
+0

Che ha funzionato perfettamente. Grazie per aver spiegato anche il motivo! – Astaar

+0

impressionante esplosione! –

Problemi correlati