Nhibernate从1.0.2.0迁移到2.1.2以及多对一保存问题

时间:2010-05-18 14:16:50

标签: nhibernate upgrade many-to-one

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

让我们说我们必须对象Blog和Post。博客可以有很多帖子,所以Post会有多对一的关系。由于此应用程序的运行方式,关系不是通过主键,而是通过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

在旧的nhibernate这样的事情是可能的:

        //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);

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

如何解决这个问题?我无法更改数据库设计,也无法为BlogEntity分配ID,因为对象不受我的控制(它们预先填充为来自外部源的通用“ojbects”)

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

blog.Id = Guid.Empty

在DB中被翻译为null。因此,当您更改它时(如示例代码所示),您将在BlogEntity Id上明确设置空值。

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

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

答案 2 :(得分:0)

回答我自己的问题。

问题是nhibernate正在等待DB检索具有标识00000000-0000-0000-0000-000000000000的BlogEntity。当然在DB中它什么都没有,所以它试图插入null

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

  

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

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

问题解决了。