0

我们有一个带有 nhibernate 的旧的大型 asp.net 应用程序,我们正在扩展和升级它的某些部分。使用的 NHibernate 已经很老了(1.0.2.0),所以我们决定升级到(2.1.2)以获得新功能。HBM 文件是通过 MyGeneration 的自定义模板生成的。一切都很顺利,除了一件事。

假设我们必须对象博客和帖子。博客可以有很多帖子,所以帖子会有多对一的关系。由于此应用程序的操作方式,关系不是通过主键,而是通过 Blog.Reference 列。

示例映射和 .cs 文件:

<?xml version="1.0" encoding="utf-8" ?>

    <id name="Id" column="Id" type="Guid">
        <generator class="assigned"/>
    </id>
    <property column="Reference" type="Int32" name="Reference" not-null="true" />
    <property column="Name" type="String" name="Name" length="250" />
</class>

<?xml version="1.0" encoding="utf-8" ?>

    <id name="Id" column="Id" type="Guid">
        <generator class="assigned"/>
    </id>

    <property column="Reference" type="Int32" name="Reference" not-null="true" />
    <property column="Name" type="String" name="Name" length="250" />
    <many-to-one name="Blog" column="BlogId" class="SampleNamespace.BlogEntity,SampleNamespace" property-ref="Reference" />
</class>

和类文件

class BlogEntity
{
    public Guid Id { get; set; }
    public int Reference { get; set; }
    public string Name { get; set; }
}

class PostEntity
{
    public Guid Id { get; set; }
    public int Reference { get; set; }
    public string Name { get; set; }
    public BlogEntity Blog { get; set; }
}

现在假设我有一个 ID 为 1D270C7B-090D-47E2-8CC5-A3D145838D9C 和参考文献 1 的博客

在旧的休眠中,这样的事情是可能的:

        //this Blog already exists in database
        BlogEntity blog = new BlogEntity();
        blog.Id = Guid.Empty;
        blog.Reference = 1; //Reference is unique, so we can distinguish Blog by this field
        blog.Name = "My blog";

        //this is new Post, that we are trying to insert
        PostEntity post = new PostEntity();
        post.Id = Guid.NewGuid();
        post.Name = "New post";
        post.Reference = 1234;
        post.Blog = blog; 

        session.Save(post);

但是,在新版本中,我得到一个异常,无法将 NULL 插入 Post.BlogId。据我了解,在旧版本中,对于 nhibernate 来说,拥有 Blog.Reference 字段就足够了,它可以通过该字段检索实体,并将其附加到 PostEntity,并且在保存 PostEntity 时,一切都会正常工作。据我了解,新的 NHibernate 仅尝试通过 Blog.Id 检索。

如何解决这个问题?我无法更改数据库设计,也无法将 Id 分配给 BlogEntity,因为对象超出了我的控制范围(它们像这样从外部源预填充为通用“ojbects”)

4

3 回答 3

0

对我来说,代码在 NH 1 中工作似乎很奇怪。但是,由于它目前无法正常工作,我认为您必须首先在查询中查找博客实体:

var criteria = DetachedCriteria.For<Blog>();
criteria.Add(Expression.Eq("Reference", 1));
var blog = criteria.GetExecutableCriteria(session).List<Blog>().FirstOrDefault();

post.Blog = blog;
session.Save(post);
于 2010-05-18T18:45:11.030 回答
0

这个

blog.Id = Guid.Empty

在数据库中被翻译为空值。因此,当您更改它时(如示例代码所示),您将在 BlogEntity Id 上显式设置一个空值。

这是您收到的错误,与“参考”列/属性无关。

至于你能做什么的问题......好吧,你不必让ORM加入Guids!您可以在“参考”列上进行连接...

于 2010-05-19T08:23:40.623 回答
0

回答我自己的问题。

问题是 nhibernate 正在访问 DB 以检索 ID 为 00000000-0000-0000-0000-000000000000 的 BlogEntity。当然在 DB 中它什么也没有,所以它试图插入 null

并且在日志中可以清楚地看到它发生的原因

无法确定分配标识符为 00000000-0000-0000-0000-000000000000 的 BlogEntity 是暂时的还是分离的;查询数据库。在会话中使用显式 Save() 或 Update() 来防止这种情况。

解决了我的实现IInterceptor,将它传递给 Session 尤其是它的方法bool? IsTransient(object entity)

并且问题解决了。

于 2010-06-10T15:09:56.593 回答