NHibernate HiLo不会在集合中的对象上生成ID

时间:2011-05-17 22:19:12

标签: collections fluent-nhibernate hilo

我正在使用NHibernate和HiLo策略,我的问题是在Session.Save()上没有生成集合中对象的ID(仅在Transaction.Commit()上)。 例如:

ImageGallery imageGallery = imageGalleryRepository.GetById(imgGalleryId);
imageGallery.Images.Add(new Image());
imageGalleryRepository.Save(imageGallery); // Here I need to access ID propery of new image in Images collection but it's 0 until I commit transaction. Can it be done?

这是我的代码:

public abstract class Entity
{
    public virtual int Id { get; set; }
}

public class ImageGallery : Entity
{
    public virtual IList<Image> Images { get; set; }
    // ...
}

public class Image : Entity
{
    public string FileName { get; set; }
    public ImageGallery ImageGallery { get; set; }
    // ...
}

映射:

public class ImageGalleryMap : ClassMap<ImageGallery>
{
    public ImageGalleryMap()
    {
        Id(x => x.Id).GeneratedBy.HiLo("hibernate_unique_key", "next_hi_image_gallery", "10");
        HasMany(x => x.Images).
            Cascade.All().
            KeyColumn("GalleryId").
            Inverse().
            Fetch.Join();
    }
}

public class GalleryImageMap : ClassMap<GalleryImage>
{
    public GalleryImageMap()
    {
        Id(x => x.Id).GeneratedBy.HiLo("hibernate_unique_key", "next_hi_image", "10");
        Map(x => x.FileName);
        References(x => x.ImageGallery).Column("GalleryId");
    }
}

2 个答案:

答案 0 :(得分:2)

Session.Save不一定刷新对数据库的更改。会话是包含数据库更改的工作单元。它不一定立即将更改发布到数据库。请看一下使用Session.Flush()。请阅读以下内容以获取更详细的说明:

http://www.nhforge.org/doc/nh/en/index.html#manipulatingdata-flushing

修改

当您有双向关系时,您还希望从代码角度来维护它。所以你需要做这样的事情:

ImageGallery imageGallery = imageGalleryRepository.GetById(imgGalleryId);
Image newImage = new Image();
newImage.ImageGallery = imageGallery;
imageGallery.Images.Add(newImage);

imageGalleryRepository.Save(imageGallery);

通常我在我的实体中使用添加/删除方法来执行此操作,而不是在上面的代码中明确地执行此操作。

如果此答案或此处的任何其他答案对您有帮助,请单击复选标记将其标记为答案。

答案 1 :(得分:0)

在刷新并转到数据库之前,不会发生现有对象的级联更改。如果要拥有与会话关联的新对象(图像),则需要通过在会话上调用save并传递新对象将其添加到会话本身。当你有一个新的图库对象添加到会话时,它会遍历对象图并添加引用的子对象。

也(不是很重要,但只是指出),你不需要为你已经从getbyid会话中获得的库本身调用save。它已经存在于会话中,当会话刷新时,它将保持对它的任何更改。 save实际上更像是一个向会话中添加内容的操作。它并不关心你是否尝试添加已存在的东西,它实际上并没有做任何事情。