带有SubclassMap的流畅NHibernate 1.2导致“没有给定标识符的行”错误

时间:2011-04-04 15:23:20

标签: nhibernate fluent-nhibernate mapping

我正在尝试升级到Fluent NHibernate 2.1(Build#694)。因此,我也升级到NHibernate 3.0。我遇到了“Table-Per-Subclass”映射的问题,这在尝试检索数据时会导致错误。

重要说明:这些表和类使用现在已弃用的“Joined-Subclass”映射版本,它存在于以前版本的FluentNhibernate中,它允许子类拥有自己的唯一ID。

我已将代码削减到最小的部分,所以让我通过代码解释一下,它会变得更加清晰:

以下是涉及的表格:

Tables

以下是表示表格的类:

public class Field
{
    public virtual int Id { get; set; }
    public virtual string Code { get; set; }
    public virtual string Description { get; set; }
}
public class MenuItem : Field
{
    public virtual string NavigateUrl { get; set; }
}
public class UserLink 
{
    public virtual int Id { get; set; }
    public virtual string ExternalLinkName { get; set; }
    public virtual MenuItem MenuItem { get; set; }
    public virtual int UserId { get; set; }
}

以下是相应的映射:

public class FieldMap : ClassMap<Field>
{
    public FieldMap()
    {
        Table("Field");
        Id(x => x.Id, "ID").GeneratedBy.Identity();
        Map(x => x.Code, "Code");
        Map(x => x.Description, "Description");
    }
}
public class MenuItemMap : SubclassMap<MenuItem>
{
    public MenuItemMap()
    {
        Table("MenuItem");
        Map(x => x.NavigateUrl, "NavigateUrl");
    }
}
public class UserLinkMap : ClassMap<UserLink>
{
    public UserLinkMap()
    {
        Table("UserLink");
        Id(x => x.Id, "ID").GeneratedBy.Identity();
        Map(x => x.ExternalLinkName, "ExternalLinkName");
        Map(x => x.UserId, "User_ID");
        References(x => x.MenuItem).Column("ID");
    }
}

以下是测试:

[Test]
    public void CanRetrieveUserLinks()
    {
        ISession session = GetSession();

        DetachedCriteria criteria = DetachedCriteria.For(typeof (UserLink))
            .Add(Restrictions.Eq("UserId", 1));

        ICriteria executableCriteria = criteria.GetExecutableCriteria(session);
        var userLinks = executableCriteria.List<UserLink>();

        Assert.IsFalse(string.IsNullOrEmpty(userLinks[0].MenuItem.NavigateUrl));

        session.Close();
    }

执行Assert行时,生成的SQL不正确,因为尝试按Field_ID而不是ID 查找MenuItem。因此,我收到错误:NHibernate.ObjectNotFoundException: No row with the given identifier exists[AS.AIMS.DomainModel.MenuItem#11]

首先生成sql以检索userLinks,这是正确的:

SELECT this_.ID               as ID2_0_,
   this_.ExternalLinkName as External2_2_0_,
   this_.User_ID          as User3_2_0_
   FROM   UserLink this_
  WHERE  this_.User_ID = 1 /* @p0 */

然后要检索菜单项,它使用Field_Id而不是ID:

SELECT menuitem0_.Field_id      as ID0_0_,
   menuitem0_1_.Code        as Code0_0_,
   menuitem0_1_.Description as Descript3_0_0_,
   menuitem0_.NavigateUrl   as Navigate2_1_0_
  FROM   MenuItem menuitem0_
 inner join Field menuitem0_1_
         on menuitem0_.Field_id = menuitem0_1_.ID
 WHERE  menuitem0_.Field_id = 11 /* @p0 */

1 个答案:

答案 0 :(得分:1)

看看我是如何做到这一点的,我唯一能看到的是,在数据库上(在你的情况下),MenuItem只有一个Field_ID。这将与场上的ID有关。

如果您在MenuItem上删除ID并将Field_ID作为键,它是否有效。像这样:

MENUITEM                  FIELD

#Field_ID   <---------->  #ID
NavigateUrl               Code        
(Removed Code, Desc)      Description