【问题标题】:Nhibernate self join read join field valueNhibernate 自连接读取连接字段值
【发布时间】:2014-02-03 00:50:22
【问题描述】:

我打算读取我的自联接映射的引用字段 (ParentMenu) 值。类和映射如下;

public class MenuSetup
{
    public virtual int MenuId { get; set; }
    public virtual string DisplayText { get; set; }
    public virtual int MenuOrder { get; set; }
    public virtual bool MenuStatus { get; set; }
    public virtual bool HasKids { get; set; }

    public virtual MenuSetup Parent { get; set; }
    public virtual ICollection<MenuSetup> SubMenu { get; set; }
 }

下面的映射;

public MenuSetupMap()
    {
        Id(x => x.MenuId).GeneratedBy.Identity();
        Map(x => x.DisplayText);
        Map(x => x.MenuStatus);
        Map(x => x.MenuOrder);
        Map(x => x.HasKids);
        HasMany(x => x.SubMenu).KeyColumn("ParentMenu"); 
        References(x => x.Parent).Column("ParentMenu"); 
            .Cascade.AllDeleteOrphan()
            .Fetch.Join().Inverse().KeyColumn("MenuId");
    }

有一个 ParentMenu 字段我想像这样读取到我的视图模型 HomeMenuViewModel 中。

var session = MvcApplication.SessionFactory.GetCurrentSession();
string qry = @"select p.MenuId,p.DisplayText,p.MenuStatus,p.MenuOrder,
m from MenuSetup as p left join p.Parent m";
var vm=session.CreateQuery(qry).List<object[]>()
            .Select(x=>new HomeMenuViewModel()
            {
                 MenuId=(int)x[0], 
                 DisplayText=(string)x[1], 
                 MenuStatus=(Boolean)x[2], 
                 MenuOrder=(int)x[3],
                 ParentMenu = x[10] == null ? 0 : (int)x[10]
            }).ToList();

抛出错误“System.IndexOutOfRangeException 未被用户代码处理”。我被卡住了,真的需要帮助。

NHProf 生成的查询如下所示;

   select menusetup0_.MenuId      as col_0_0_,
   menusetup0_.DisplayText as col_1_0_,
   menusetup0_.MenuStatus  as col_2_0_,
   menusetup0_.MenuOrder   as col_3_0_,
   menusetup1_.MenuId      as col_4_0_,
   menusetup1_.MenuId      as MenuId10_,
   menusetup1_.DisplayText as DisplayT2_10_,
   menusetup1_.MenuStatus  as MenuStatus10_,
   menusetup1_.MenuOrder   as MenuOrder10_,
   menusetup1_.HasKids     as HasKids10_,
   menusetup1_.ParentMenu  as ParentMenu10_
   from   [MenuSetup] menusetup0_
   left outer join [MenuSetup] menusetup1_
     on menusetup0_.ParentMenu = menusetup1_.MenuId

真诚地等待帮助。

谢谢

更新解决方案

经过多次修改,我找到了解决方案

我需要在 MenuSetup 类中声明该字段,如下所示

public class MenuSetup
{
    .
    .
    public virtual int ParentMenu { get; set; }
    .
}

在 Mapping 类中,我也声明了该列。

我的检索码改为

var session = MvcApplication.SessionFactory.GetCurrentSession();
string qry = @"select p.MenuId,p.DisplayText,p.MenuStatus,p.MenuOrder,
              p.ParentMenu from MenuSetup as p";
var vm=session.CreateQuery(qry).List<object[]>()
        .Select(x=>new HomeMenuViewModel()
        {
             MenuId=(int)x[0], 
             DisplayText=(string)x[1], 
             MenuStatus=(Boolean)x[2], 
             MenuOrder=(int)x[3],
             ParentMenu = x[4] == null ? 0 : (int)x[4]
        }).ToList();

【问题讨论】:

    标签: nhibernate fluent-nhibernate hql fluent-nhibernate-mapping self-join


    【解决方案1】:

    object[] 项的数量与 HQL 查询有关,与生成的 SQL 查询无关。 IE。上面的查询将返回 object[] 有 5 个元素:

    // the HQL Snippet
    select 
    p.MenuId,      // object[0]
    p.DisplayText, // object[1]
    p.MenuStatus,  // object[2]
    p.MenuOrder,   // object[3]
    m              // object[4]
    from MenuSetup ....
    

    所以,没有object[10] ...这就是为什么我们有System.IndexOutOfRangeException

    5th 元素是完全父元素。解决方案应该是这样的:

    ParentMenu = x[4] == null ? null : (MenuSetup)x[4]
    

    注意:如果我们只使用父级的一个属性可能会更好,例如将 HQL 更改为 ...m.DisplayText...

    【讨论】:

    • Radim,我真正需要的是阅读 ParentMenu。感谢您的帮助
    • 另一个可行的解决方案,没有扩展MenuSetup 实体及其映射,在我的Note中。只需更改 HQL 以选择 m.Parent.MenuId... 并且您的 int id 为第 5 个 object[] 项目
    • 您的解决方案更优雅。我的解决方案在映射中引入了一些与重复相关的错误。我已经实现了你的。谢谢
    • 很高兴看到这一点。祝 NHiberante 好运。惊人的工具
    猜你喜欢
    • 2011-12-18
    • 2018-07-04
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 2011-10-04
    • 2012-03-06
    • 1970-01-01
    相关资源
    最近更新 更多