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

发布于 2024-11-07 13:01:41 字数 1573 浏览 5 评论 0原文

我正在使用 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");
    }
}

I'm using NHibernate and HiLo strategy and my problem is that IDs of objects in collections are not generated on Session.Save() (only on Transaction.Commit()).
For example:

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?

Here's the code that I have:

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; }
    // ...
}

Mappings:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

囍孤女 2024-11-14 13:01:41

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

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

编辑:

当您有双向关系时,您还希望从代码角度维护它。因此,您需要执行以下操作:

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

imageGalleryRepository.Save(imageGallery);

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

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

Session.Save does not necessarily Flush the changes to the database. Session is a unit of work that contains database changes. It does not necessarily post the changes to the database right away. Please take a look at using Session.Flush(). Please read the following for a more detailed description:

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

Edit:

When you have a bidirectional relationship you also want to maintain this from the code perspective. So you would need to do something like this:

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

imageGalleryRepository.Save(imageGallery);

Generally I use Add/Remove methods in my entities to do this instead of explicitly doing it in the code above.

If this answer or any other answer here helps you please click the check mark marking it as the answer.

始终不够爱げ你 2024-11-14 13:01:41

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

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

cascading changes for an existing object does not happen until you flush and go to the database. if you want to have a new object (the image) associated with the session, you need to add it to the session itself by calling save on the session and passing the new object. when you have a new gallery object you are adding to the session, it does traverse the object graph and add the referenced children.

also (not very important, but just to point out), you don't need to call save for the gallery itself that you already got from the session with getbyid. it's already there in the session and any changes to it will be persisted when the session flushes. save is really more of an operation to add something to the session. it doesn't care if you try to add something that is already there, it just doesn't really do anything.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文