【问题标题】:Fluent NHibernate 1.2 with SubclassMap causes "No row with the given identifier" errorFluent NHibernate 1.2 with SubclassMap 导致“No row with the given identifier”错误
【发布时间】:2011-07-29 06:45:01
【问题描述】:

我正在尝试升级到 Fluent NHibernate 2.1(内部版本 #694)。结果,我也升级到 NHibernate 3.0。我遇到了“每个子类的表”映射问题,在尝试检索数据时会导致错误。

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

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

以下是涉及的表格:

以下是代表表的类:

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 */

【问题讨论】:

  • fluent 1.2 / nh3.1 今天上线了。 fluentnhibernate.org/blog/2011/04/03/…
  • 这不是您的完整代码,是吗? menuitem 子类映射来自什么?
  • MenuItem 是 Field 的子类。这是在类声明中定义的:public class MenuItem : Field
  • Kohan - 在 FluentNhibernate 网站的下载部分,我没有看到新版本的链接。

标签: nhibernate fluent-nhibernate mapping


【解决方案1】:

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

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

MENUITEM                  FIELD

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

【讨论】:

  • 因此,我将 UserLinkMap 中的行更改为:References(x =&gt; x.MenuItem).Column("Field_ID");,但我收到错误消息,因为它试图从 UserLink 表中检索 Field_ID,而该表当然不存在。
  • 抱歉,我的意思是在您的数据库中,而不是在映射中。我觉得它们很好。
  • Kohan - 感谢您的帮助,这似乎按预期工作。我想我想知道我以前的想法是错误的还是可以以其他方式完成?我希望 MenuItem 表有自己的唯一标识符。我之所以这么问,是因为我拥有的这个小示例是现实世界应用程序的一个非常简单的版本,它要大得多,并且以这种方式对表和映射进行更改将是一项非常大的工作。
  • 它仍然有一个唯一的“ID”,Field_ID。我开始认为您不想使用子类。请问这是为什么?
  • @Kohan - 本质上,为每个表设置一个唯一标识符已经成为一种标准。也可以使用外键,只是我们一般不使用它们作为主键。因此,在保存 MenuItem 时,如果有一些东西可以固有地保存 Field 记录和 MenuItem 记录,那就太好了。此外,这一切都适用于 JoinedSubClass 和以前的 Fluent 版本。
猜你喜欢
  • 1970-01-01
  • 2016-01-08
  • 2019-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2014-11-14
相关资源
最近更新 更多