【发布时间】: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