如何防止使用nHibernate插入重复数据?

如何防止使用nHibernate插入重复数据?,nhibernate,unique,Nhibernate,Unique,我正在建立一个博客/CMS系统(为了好玩,我知道有很多东西我可以使用)。 我有一个简单的标记实体,它只有一个Id(int)和一个标记名(string)属性。我希望配置nHibernate,以便执行以下操作: var tag1 = Tag.CreateTag("duplicate tag test"); // Id=0 at this point var tag2 = Tag.CreateTag("duplicate tag test"); // Id=0 at this point TagR

我正在建立一个博客/CMS系统(为了好玩,我知道有很多东西我可以使用)。
我有一个简单的标记实体,它只有一个Id(int)和一个标记名(string)属性。我希望配置nHibernate,以便执行以下操作:

var tag1 = Tag.CreateTag("duplicate tag test");  // Id=0 at this point
var tag2 = Tag.CreateTag("duplicate tag test");  // Id=0 at this point
TagRepository.Save(tag1);  // tag1.Id is non-zero
TagRepository.Save(tag2);  // tag2.Id should be the same as tag1.Id at this point, but it's not

Assert.AreEqual(tag1, tag2);
我设想Save(Tag)执行类似于查找的操作,如果该标记已经存在,则以某种方式用tag1的值替换tag2。nHibernate使用了一些魔法来修改参数的属性,即使它不是作为out参数传递的。有人能告诉我这里发生了什么,以及如何修正这个方法来做我想做的事情吗?我试图避免在tag参数上使用out关键字

    public override void Save(Tag tag)
    {
        Tag existingTag = GetByTagName(tag.TagName);
        if (null == existingTag)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            using (ITransaction transaction = session.BeginTransaction())
            {
                session.SaveOrUpdate(tag);
                transaction.Commit();
            }
        }
        else
        {
            tag = existingTag; // obviously doesn't impact the caller
        }
    }

我认为您对“out参数”的引用没有意义。对象仍然是相同的实例,但NH在保存时已将ID更新为生成的ID

我认为您必须首先获取标记,就像您在示例中所做的那样。如果您想让来电者看到正确的id,请执行以下操作

tag.id = existingTag.id;

我认为你的问题与参数以及如何处理它们有关,而不是与NHibernate有关。阅读本书,了解这些东西的工作原理。

我认为你提到的“out参数”没有意义。对象仍然是相同的实例,但NH在保存时已将ID更新为生成的ID

我认为您必须首先获取标记,就像您在示例中所做的那样。如果您想让来电者看到正确的id,请执行以下操作

tag.id = existingTag.id;

我认为你的问题与参数以及如何处理它们有关,而不是与NHibernate有关。阅读本书,了解这些东西是如何工作的。

这段代码会插入重复的内容吗?你能再解释一下吗?不,这个代码没有。如果我删除GetByTagName调用/检查,它会删除。我要寻找的是nHibernate如何修改传递给方法的标记对象的Id字段。它不是out参数,但是在Save方法返回后,在创建新标记时,tag.Id从0更改为非零。当标签已经存在时,我希望发生同样的事情(也就是说,实现一个FindOrInsert类型的方法。这段代码插入了重复的代码?你能再解释一下吗?不,这段代码没有。如果我删除GetByTagName调用/检查,它会。我要寻找的是nHibernate如何修改传递给该方法的标记对象的Id字段。它不是一个out参数,但在Save me之后thod返回,当创建新标记时,tag.Id从0更改为非零。我希望当标记已经存在时也会发生同样的情况(即实现FindOrInsert类型的方法)。