Свободный NHibernate "Не удалось разрешить свойство"
Я прочитал много вопросов об этой же ошибке, но ни один из них не соответствует моей точной проблеме. Я пытаюсь получить доступ к свойству объекта, самой части корневого объекта, используя Fluent NHibernate. Некоторые ответы говорят, что мне нужно использовать прогнозы, другие, которые мне нужно использовать, и я думаю, что это должно работать через ленивую загрузку.
Вот мои два класса вместе с Fluent-сопоставлениями:
Класс артиста
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);
}
}
Класс альбома
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);
}
}
И ошибка возникает, когда этот код интерпретируется:
var riAlbum = session.QueryOver<Album>()
.Where(x => x.Name == albumName && x.Artist.Name == artist)
.List().FirstOrDefault();
Ошибка происходит, когда Fluent NHibernate пытается разрешить значение x.Artist.Name:
{ "не удалось разрешить свойство: Artist.Name of: Album" }
Каким будет правильный способ сделать это?
Ответы
Ответ 1
Вы должны думать о своем запросе QueryOver как (почти), непосредственно переводимом в SQL. Имея это в виду, представьте этот SQL-запрос:
select
Album.*
from
Album
where
Album.Name = 'SomeAlbumName' and
Album.Artist.Name = 'SomeArtistName'
Это не будет работать, потому что вы не можете получить доступ к связанным свойствам таблицы, подобным этому в инструкции SQL. Вам нужно создать соединение от Album
до Artist
, а затем использовать предложение Where
:
var riAlbum =
session.QueryOver<Album>()
.Where(al => al.Name == albumName)
.JoinQueryOver(al => al.Artist)
.Where(ar => ar.Name == artistName)
.List()
.FirstOrDefault();
Кроме того, поскольку вы используете FirstOrDefault
, вам может потребоваться переместить эту логику в конец базы данных. В настоящее время вы отбираете все записи, соответствующие вашим критериям, а затем принимаете первый. Вы можете использовать .Take
, чтобы ограничить запрос до 1 результата:
var riAlbum =
session.QueryOver<Album>()
.Where(al => al.Name == albumName)
.JoinQueryOver(al => al.Artist)
.Where(ar => ar.Name == artistName)
.Take(1)
.SingleOrDefault<Album>();