我无法理解为什么这不起作用..
我有一个相对干净的实体模型,包括用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”.