2

我正在使用 NHibernate 和 HiLo 策略,我的问题是集合中对象的 ID 不是在 Session.Save() 上生成的(仅在 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");
    }
}
4

2 回答 2

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

通常,我在我的实体中使用 Add/Remove 方法来执行此操作,而不是在上面的代码中显式执行此操作。

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

于 2011-05-18T00:43:26.100 回答
0

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

另外(不是很重要,只是要指出),您不需要为您已经从使用 getbyid 的会话中获得的画廊本身调用 save。它已经存在于会话中,并且在会话刷新时对它的任何更改都将保留。保存实际上更像是向会话添加内容的操作。它并不关心您是否尝试添加已经存在的东西,它实际上并没有做任何事情。

于 2011-11-28T18:01:55.353 回答