c# – 流利的NHibernate“无法解析属性”

前端之家收集整理的这篇文章主要介绍了c# – 流利的NHibernate“无法解析属性”前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经阅读了很多关于相同错误的问题,但是没有一个是为了匹配我的确切问题.我正在使用Fluent NHibernate访问对象的属性,本身是根对象的一部分.有些答案说我需要使用预测,其他的我需要使用加入,我认为它应该通过懒惰加载工作.

这是我的两个课程以及流畅的映射:

艺术家类

  1. public class Artist
  2. {
  3. public virtual int Id { get; set; }
  4. public virtual string Name { get; set; }
  5. public virtual IList<Album> Albums { get; set; }
  6. public virtual string MusicBrainzId { get; set; }
  7. public virtual string TheAudioDbId { get; set; }
  8.  
  9. public Artist() { }
  10. }
  11.  
  12. public class ArtistMap : ClassMap<Artist>
  13. {
  14. public ArtistMap()
  15. {
  16. LazyLoad();
  17. Id(a => a.Id);
  18. Map(a => a.Name).Index("Name");
  19. HasMany(a => a.Albums)
  20. .Cascade.All();
  21. Map(a => a.MusicBrainzId);
  22. Map(a => a.TheAudioDbId);
  23. }
  24. }

专辑类

  1. public class Album
  2. {
  3. public virtual int Id { get; set; }
  4. public virtual Artist Artist { get; set; }
  5. public virtual string Name { get; set; }
  6. public virtual IList<Track> Tracks { get; set; }
  7. public virtual DateTime ReleaseDate { get; set; }
  8. public virtual string TheAudioDbId { get; set; }
  9. public virtual string MusicBrainzId { get; set; }
  10.  
  11. public Album() { }
  12. }
  13.  
  14. public class AlbumMap : ClassMap<Album>
  15. {
  16. public AlbumMap()
  17. {
  18. LazyLoad();
  19. Id(a => a.Id);
  20. References(a => a.Artist)
  21. .Cascade.All();
  22. Map(a => a.Name).Index("Name");
  23. HasMany(a => a.Tracks)
  24. .Cascade.All();
  25. Map(a => a.ReleaseDate);
  26. Map(a => a.TheAudioDbId);
  27. Map(a => a.MusicBrainzId);
  28. }
  29. }

当这个代码被解释时,会发生错误

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

当Fluent NHibernate尝试解析x.Artist.Name值时,会发生错误

{“could not resolve property: Artist.Name of: Album”}

这样做的正确方法是什么?

解决方法

您必须将QueryOver查询视为(几乎)直接翻译成sql.考虑到这一点,想象这个SQL查询
  1. select
  2. Album.*
  3. from
  4. Album
  5. where
  6. Album.Name = 'SomeAlbumName' and
  7. Album.Artist.Name = 'SomeArtistName'

这将无法正常工作,因为您无法在sql语句中访问相关表的属性.您需要创建一个从Album到Artist的连接,然后使用Where子句:

  1. var riAlbum =
  2. session.QueryOver<Album>()
  3. .Where(al => al.Name == albumName)
  4. .JoinQueryOver(al => al.Artist)
  5. .Where(ar => ar.Name == artistName)
  6. .List()
  7. .FirstOrDefault();

此外,由于您使用的是FirstOrDefault,您可能需要考虑将该逻辑移至数据库端.目前,您正在拉回符合您的标准的每个记录,然后取得第一个.您可以使用.Take将查询限制为1个结果:

  1. var riAlbum =
  2. session.QueryOver<Album>()
  3. .Where(al => al.Name == albumName)
  4. .JoinQueryOver(al => al.Artist)
  5. .Where(ar => ar.Name == artistName)
  6. .Take(1)
  7. .SingleOrDefault<Album>();

猜你在找的C#相关文章