Fluent-NHibernate多对多级联不会填充链接表

Ali*_*tad 11 .net c# nhibernate many-to-many fluent-nhibernate

好的,无论我如何定义这些映射,我的多对多映射都不希望使用级联插入.我已经尝试了各种组合Cascade()使用Reverse()和删除所有不必要的属性,只是为了了解它们是否与此无关,但没有锁定.

这是非常简单的东西:我有一个Message(像一个电子邮件)从用户(我已经称实体BasicUser)发送给许多用户(通过财产To).User并且Message在接受者方面具有多对多的关系,但FromUser具有一对多的关系.FromUser工作正常,它更新正常,但我的问题是多对多.我甚至删除FromUser和关系只是为了检查这是否是问题,但没有帮助.

因此,这里的表设计(从删除的关系FromUserBasicUser为简单起见)

在此输入图像描述

以下是映射:

public class MessageMap : ClassMap<Message>
{

    public MessageMap()
    {
        Id(x => x.Id).Column("MessageId");
        Map(x => x.Subject);
        Map(x => x.SentAt);
        Map(x => x.Body);
        References(x => x.From).Column("FromUser");
        HasManyToMany(x => x.To).Table("BasicUserMessage").ChildKeyColumn("BasicUserId")
            .ParentKeyColumn("MessageId").Cascade().All();
    }
}

public class BasicUserMap : ClassMap<BasicUser>
{
    public BasicUserMap()
    {
        Id(x => x.Id).Column("BasicUserId");
        Map(x => x.DisplayName);
        Map(x => x.Username);
        HasManyToMany(x => x.Messages).Table("BasicUserMessage").ChildKeyColumn("MessageId")
            .ParentKeyColumn("BasicUserId").Inverse();
    }
}
Run Code Online (Sandbox Code Playgroud)

我打电话给它,它不起作用(表BasicUserMessage没有填充):(注意Id 1,2和3的用户确实存在 - 我也尝试从数据库中获取它们然后添加到列表仍然无法工作)

ISessionFactory factory = GetSessionFactory();
ISession session = factory.OpenSession();
Message m = new Message()
                {
                    Body = "Please note 2",
                    Subject = "Secret 2",
                    From = new BasicUser(){Id = 2},
                    SentAt = DateTime.Now,
                };
m.To.Add(new BasicUser(){Id = 1});
m.To.Add(new BasicUser(){Id=3});
session.SaveOrUpdate(m);
session.Close();
Run Code Online (Sandbox Code Playgroud)

Mat*_*ght 6

关于交易的答案是偶然发生的.同样正确的发生是因为你正在使用像IDENTITY生成器之类的东西,需要在保存时获取数据库,以获得身份.

以下是NHibernate在save-update与多对多关联设置级联(或任何暗示的级联)时所做的事情:

保存父实体.由于身份策略,这会立即进入数据库.该集合被"修改"(因为它是新的),所以让我们来看看它的成员.仅当inverse未在父关系的映射上设置此步骤时才会发生此步骤.在链接表中为每个条目创建一个条目.

但等等,其中一些条目是短暂的.Cascades设置正确,所以没关系 - 但是为了在会话中创建链接表条目,我们需要这些子节点的id,所以让我们立即保存它们.

现在所有相关实体都是持久的,并且会话具有链接表中所有条目的挂起插入.刷新会话将发出命令并创建这些条目.

在事务中包装代码时,提交事务会刷新会话,以便在提交时创建.如果您使用不需要DB往返的身份生成器,那么链接表条目和实体都会同时插入,因此您将看不到您所看到的"断开连接" - 如果会话永远不会被刷新,什么都没有被插入,当它被刷新时,一切都被插入.如果你没有这些东西,显式刷新你的会话将创建链接表条目,一切都会很好.


Ste*_*ger 5

你把两个引用都反过来了.这意味着NH:不要从这一侧存储它,因为它已经存储在另一侧.如果两者都是反向的,则不存储任何内容

从其中一个引用中删除Inverse.