c# – 流利的Nhibernate ManyToMany集合 – 不保存关联

我无法理解为什么这不起作用..

我有一个相对干净的实体模型,包括用DDD创建的POCO(虽然可能不会松散地遵循大多数规则).

我正在使用Fluent NHibernate进行映射.我也使用SchemaExport来创建数据库模式,我最少的输入是如何做到的. NHibernate可以自由选择最佳方式.

我有两个实体,彼此之间存在多对多的关系(删除了非有趣的代码); MediaItem和Tag; MediaItems可以有很多标签,标签可以应用于许多MediaItems,我想要双方收藏,这样我就可以轻松搞定.

(下面有点格式化问题,对不起)

> MediaItem:

public class MediaItem
{

private IList<Tag> _tags;

public virtual long Id { get; set; }

public virtual string Title { get; set; }

public virtual IEnumerable<Tag> Tags { get { return _tags; } }

public MediaItem()
{
    _tags = new List<Tag>();
}

public virtual void AddTag(Tag newTag)
{
    _tags.Add(newTag);
    newTag.AddMediaItem(this);
}

}
>标签:

公共类标签
{

private IList<MediaItem> _mediaItems;
public virtual long Id { get; set; }
public virtual string TagName { get; set; }
public virtual IEnumerable<MediaItem> MediaItems { get { return _mediaItems; } }

public Tag()
{
    _mediaItems = new List<MediaItem>();
}

protected internal virtual void AddMediaItem(MediaItem newItem)
{
    _mediaItems.Add(newItem);
}

}

我试图聪明地将集合暴露为IEnumerable,并且只允许通过方法添加项目.我也听说只有关系的一方应对此负责 – 因此在Tag上设计的AddMediaItem().

MediaItemMap如下所示:

public class MediaItemMap : ClassMap<MediaItem>
{
    public MediaItemMap()
    {
        Table("MediaItem");

        Id(mi => mi.Id);

        Map(mi => mi.Title);

        HasManyToMany<Tag>(mi => mi.Tags)
            .Access.CamelCaseField(Prefix.Underscore)
            .Cascade.SaveUpdate();
    }
}

标签映射如下所示:

public class TagMap : ClassMap<Tag>
{
    public TagMap()
    {
        Table("Tag");

        Id(t => t.Id);

        Map(t => t.TagName);

        HasManyToMany<MediaItem>(mi => mi.MediaItems)
            .Access.CamelCaseField(Prefix.Underscore)
            .Inverse();
    }
}

现在我有一些测试代码可以删除数据库模式,重新创建它(因为我在这里调试我的大脑),然后运行以下简单代码:

Tag t = new Tag { TagName = "TestTag" };
MediaItem mi = new MediaItem { Title = "TestMediaItem" };

mi.AddTag(t);

var session = _sessionFactory.OpenSession();

session.Save(mi);

是的,这是测试代码,它将永远不会超过这篇文章中的问题.

MediaItem已保存,Tag也是如此.但是,他们之间的关联不是. NHibernate会创建关联表“MediaItemsToTags”,但它不会尝试在其中插入任何内容.

在创建ISessionFactory时,我指定了ShowSQL() – 所以我可以看到发送到SQL服务器的所有DDL.我可以看到MediaItem和Tag表的insert语句,但没有MediaItemsToTags的插入.

我已经尝试了很多不同的版本,但我似乎无法破解它.级联是一个可能的问题,我尝试过两侧的Cascade.All(),两侧的反向()等,但没有骰子.

任何人都可以告诉我映射这个的正确方法是什么,以便NHibernate在我存储我的MediaItem时实际存储关联?

谢谢!

最佳答案 您需要定义多对多表以及父键和子键列:

public class MediaItemMap : ClassMap<MediaItem>
{
    public MediaItemMap()
    {
        Table("MediaItem");

        Id(mi => mi.Id);

        Map(mi => mi.Title);

        HasManyToMany<Tag>(mi => mi.Tags)
            .Table("MediaItemsToTags").ParentKeyColumn("Id").ChildKeyColumn("Id")
            .Access.CamelCaseField(Prefix.Underscore)
            .Cascade.SaveUpdate();
    }
}

TagMap中的语法相同,因为两个键列都命名为“Id”.

点赞