功能NHibernate"无法解析财产" [英] Fluent NHibernate "Could not resolve property"

查看:118
本文介绍了功能NHibernate"无法解析财产"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经读了很多关于同样的错误问题,但由于没有符合我确切的问题。我试图访问一个对象的属性,根对象自身的一部分,用流利的NHibernate的。一些答案说,我需要用预测,别人说我需要使用加入,我觉得应该通过延迟加载工作。



下面是我的两个班的一起流利的映射:



艺术家级

 公共类艺术家
{
公共虚拟INT标识{搞定;组; }
公共虚拟字符串名称{;组; }
公共虚拟的IList<相册和GT;相册{搞定;组; }
公共虚拟字符串MusicBrainzId {搞定;组; }
公共虚拟字符串TheAudioDbId {搞定;组; }

公共艺术家(){}
}

公共类ArtistMap:ClassMap<艺术家>
{
公共ArtistMap()
{
LazyLoad();
ID(A => a.Id);
地图(A => a.Name)的.index(姓名);
的hasMany(A => a.Albums)
.Cascade.All();
地图(A => a.MusicBrainzId);
地图(A => a.TheAudioDbId);
}
}



专辑类

 公共类专辑
{
公共虚拟INT标识{搞定;组; }
公共虚拟艺术家艺术家{搞定;组; }
公共虚拟字符串名称{;组; }
公共虚拟的IList<轨道>曲目{搞定;组; }
公共虚拟的DateTime RELEASEDATE {搞定;组; }
公共虚拟字符串TheAudioDbId {搞定;组; }
公共虚拟字符串MusicBrainzId {搞定;组; }

公共相册(){}
}

公共类AlbumMap:ClassMap<相册和GT;
{
公共AlbumMap()
{
LazyLoad();
ID(A => a.Id);
引用(A => a.Artist)
.Cascade.All();
地图(A => a.Name)的.index(姓名);
的hasMany(A => a.Tracks)
.Cascade.All();
地图(A => a.ReleaseDate);
地图(A => a.TheAudioDbId);
地图(A => a.MusicBrainzId);
}
}



当这段代码被解释发生错误:

  VAR riAlbum = session.QueryOver<相册和GT;()
。凡(X => x.Name == ALBUMNAME&功放;&安培; x.Artist.Name ==艺术家)
的.List()FirstOrDefault()。

在功能NHibernate尝试解析x.Artist.Name值发生错误:




{无法解析特性:中Artist.Name:专辑}




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


解决方案

您必须考虑您的QueryOver查询作为(几乎)直接翻译成SQL。考虑到这一点,想象一下SQL查询:



<预类=郎-SQL prettyprint-覆盖> 选择
专辑* $从
专辑
b $ b,其中
Album.Name ='SomeAlbumName'和
Album.Artist.Name ='SomeArtistName'

这是行不通的,因为你不能访问相关表的属性一样,在一个SQL语句。您需要创建从专辑 A加入到艺术家然后的使用其中,子句:

  VAR riAlbum = 
session.QueryOver<相册和GT; ()
。凡(AL => al.Name == ALBUMNAME)
.JoinQueryOver(AL => al.Artist)
。凡(AR => ar.Name = = ARTISTNAME)
的.List()
.FirstOrDefault();



此外,由于你使用 FirstOrDefault ,你可能要考虑这种逻辑移动到数据库中结束。目前,你拉回来的每条记录符合您的条件,然后采取的第一个。你可以使用。取来查询限制为1的结果:

  VAR riAlbum = 
session.QueryOver<相册和GT;()
。凡(AL => al.Name == ALBUMNAME)
.JoinQueryOver(AL => al.Artist)
。凡(AR => ar.Name == ARTISTNAME)
。取(1)
.SingleOrDefault<相册和GT;();


I have read a lot of the questions about that same error but none since to match my exact problem. I'm trying to access the property of an object, itself part of a root object, using Fluent NHibernate. Some answers say I need to use projections, others that I need to use join, and I think it should work through lazy loading.

Here are my two classes along with the Fluent mappings:

Artist class

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 class

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);
    }
}

And the error happens when this code is interpreted:

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

The error happens when Fluent NHibernate tries to resolve the x.Artist.Name value:

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

What would be the correct way of doing this?

解决方案

You have to think of your QueryOver query as (nearly) directly translating into SQL. With this in mind, imagine this SQL query:

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

This won't work because you can't access a related table's properties like that in a SQL statement. You need to create a join from Album to Artist and then use a Where clause:

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

Also, since you're using FirstOrDefault, you may want to consider moving that logic to the database end. Currently, you're pulling back every record matching your criteria and then taking the first one. You could use .Take to limit the query to 1 result:

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

这篇关于功能NHibernate&QUOT;无法解析财产&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆