5

JoinAliasを使用して複数のエンティティに参加しようとしていますが、複数のエンティティを参加させる方法がわかりません。次のコードはSQLエラーになります。

[TestMethod]
public void TestAliases()
{
    App_Start.NHibernateProfilerBootstrapper.PreStart();

    var type = new ShirtStyleType {Id = 1};
    var style = new ShirtStyle {Id = 1, ShirtStyleType = type};
    var shirt = new Shirt {Id = 1};
    var shirtStyle = new ShirtShirtStyle {Shirt = shirt, ShirtStyle = style};
    shirt.ShirtStyles = new[] {shirtStyle};

    using (Session.BeginTransaction())
        Session.Save(shirt);

    Session.Clear();

    using (Session.BeginTransaction())
    {
        Shirt shirtAlias = null;
        ShirtShirtStyle shirtStylesAlias = null;
        ShirtStyle shirtStyleAlias = null;
        ShirtStyleType shirtStyleTypeAlias = null;

        var query = Session.QueryOver<Shirt>(() => shirtAlias)
            .JoinAlias(() => shirtAlias.ShirtStyles, () => shirtStylesAlias)
            .JoinAlias(() => shirtStylesAlias.ShirtStyle, () => shirtStyleAlias)
            .JoinAlias(() => shirtStyleAlias.ShirtStyleType, () => shirtStyleTypeAlias)
            .Where(() => shirtStyleTypeAlias.Id == 1)
            .List();
    }
}

エラー:

ERROR: 
SQLite error
no such column: shirtstyle3_.Id

エラーの原因となるSQL:

SELECT this_.Id                as Id0_1_,
       shirtstyle1_.Shirt      as Shirt1_0_,
       shirtstyle1_.ShirtStyle as ShirtStyle1_0_
FROM   "Shirt" this_
       inner join "ShirtShirtStyle" shirtstyle1_
         on this_.Id = shirtstyle1_.Shirt_id
WHERE  shirtstyle3_.Id = 1 /* @p0 */

エラーが発生している理由を確認するのは非常に明白です。クエリに結合がありません。具体的には、「ShirtShirtStyle」以外のすべての結合です。私がJoinAliasを理解していることから、提供したコードは必要なテーブルを結合する必要がありますが、そうではなく、その理由もわかりません。この場合、JoinAliasを機能させるために必要なものは他にありますか?

このテスト用に作成したエンティティとマッピングは、それらがどのようにマッピングされているかに関係がある場合に備えて、以下のとおりです。

エンティティ:

public class Shirt
{
    public virtual int Id { get; set; }
    public virtual IList<ShirtShirtStyle> ShirtStyles { get; set; } 
}

public class ShirtShirtStyle
{
    public virtual Shirt Shirt { get; set; }
    public virtual ShirtStyle ShirtStyle { get; set; }

    protected bool Equals(ShirtShirtStyle other)
    {
        return Equals(Shirt, other.Shirt) && Equals(ShirtStyle, other.ShirtStyle);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((ShirtShirtStyle) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((Shirt != null ? Shirt.GetHashCode() : 0)*397) ^ (ShirtStyle != null ? ShirtStyle.GetHashCode() : 0);
        }
    }
    }

    public class ShirtStyle
    {
        public virtual int Id { get; set; }
        public virtual ShirtStyleType ShirtStyleType { get; set; }
    }

    public class ShirtStyleType
    {
        public virtual int Id { get; set; }
    }

マップ:

public class ShirtMap : ClassMap<Shirt>
{
    public ShirtMap()
    {
        Id(x => x.Id).GeneratedBy.Assigned();
        HasMany(x => x.ShirtStyles);
    }
}

public sealed class ShirtShirtStyleMap : ClassMap<ShirtShirtStyle>
{
    public ShirtShirtStyleMap()
    {
        CompositeId()
            .KeyReference(x => x.Shirt)
            .KeyReference(x => x.ShirtStyle);
    }
}

public sealed class ShirtStyleMap : ClassMap<ShirtStyle>
{
    public ShirtStyleMap()
    {
        Id(x => x.Id).GeneratedBy.Assigned();
        References(x => x.ShirtStyleType);
    }
}

public sealed class ShirtStyleTypeMap : ClassMap<ShirtStyleType>
{
    public ShirtStyleTypeMap()
    {
        Id(x => x.Id).GeneratedBy.Assigned();
    }
}
4

1 に答える 1

2

このクエリは期待どおりに機能しているようです。問題はFluentNHibernateにあるようです。参照は.KeyReferenceを介して複合エンティティで指定されますが、https://stackoverflow.com/a/10995486/981205に従って、マッピングで明示的に再指定する必要あります。これがバグなのか、予想される動作なのかわからない。

于 2012-08-15T14:10:23.080 に答える