c# - 在 NHibernate 中使用哪种算法处理多对多关系

标签 c# nhibernate many-to-many design-patterns

我在照片和标签之间建立了多对多关系:一张照片可以有多个标签,多张照片可以共享相同的标签。

我有一个循环扫描目录中的照片,然后将它们添加到 NHibernate。在此过程中,一些标签会添加到照片中,例如2009 年拍摄照片时的 2009 年标签。

Tag 类实现了 Equals 和 GetHashCode,并使用 Name 属性作为唯一的签名属性。 Photo 和 Tag 都有代理键并且是版本化的。

我有一些类似于下面的代码:

public void Import() {
    ...
    foreach (var fileName in fileNames) {
        var photo = new Photo { FileName = fileName };
        AddDefaultTags(_session, photo, fileName);
        _session.Save(photo);
    }
    ...
}

private void AddDefaultTags(…) {
    ...
    var tag =_session.CreateCriteria(typeof(Tag))
                    .Add(Restriction.Eq(“Name”, year.ToString()))
                    .UniqueResult<Tag>();

    if (tag != null) {
        photo.AddTag(tag);
    } else {
        var tag = new Tag { Name = year.ToString()) };
        _session.Save(tag);
        photo.AddTag(tag);
    }
}

我的问题是当标签不存在时,例如新年的第一张照片。 AddDefaultTags 方法检查数据库中是否存在标记,然后创建它并将其添加到 NHibernate。这在添加单张照片时效果很好,但在新的一年和同一工作单元中导入多张照片时失败,因为它仍然不存在于数据库中并再次添加。完成工作单元时失败,因为它试图在 Tags 表中添加两个具有相同名称的条目...

我的问题是如何确保 NHibernate 在上述情况下仅尝试在数据库中创建单个标记。我是否需要自己维护一个新添加标签的列表,或者我是否可以按照它可以工作的方式设置映射?

最佳答案

如果您的标准不应返回陈旧数据,您需要运行 _session.Flush()。 或者您应该能够通过将 _session.FlushMode 设置为 Auto 来正确执行此操作。

使用 FlushMode.Auto, session 将在执行标准之前自动刷新。

编辑:而且很重要!在阅读您显示的代码时,您似乎没有为您的工作单元使用事务。我建议将您的工作单元包装在一个事务中——如果您使用的是 NH2.0+,FlushMode.Auto 是工作所必需的!

在这里进一步阅读:NHibernate ISession Flush: Where and when to use it, and why?

关于c# - 在 NHibernate 中使用哪种算法处理多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/817439/

相关文章:

c# - 元胞自动机的实现

c# - NotSupportedException 与 linq 查询和 groupBy

NHibernate - 映射字符串外键

nhibernate - 在NHibernate中强制执行急切的选择

c# - Entity Framework - n 层 - 多对多 - 如何获取列表 "where"

c# - Typeahead.js 和 Bloodhound.js 与 C# WebForms WebMethod 的集成

c# - 为什么你可以在 Java 和 .Net 中反射(reflect)和调用一个(不是这样的)私有(private)方法

c# - 如何清除 LineRenderer 路径以重绘线条?

php - 从用户到帖子和类别的多态多对多

entity-framework-4 - 具有多对多自引用关系的 EF Code First