1

这是在以下代码中复制的一个奇怪的代码:

        using (ISession session = RepositoryTestHelper.SessionFactory.OpenSession())
        {
            //session.BeginTransaction();

            UserRepo repo = new UserRepo(session);
            CompanyRepo cRepo = new CompanyRepo(session);
            var user = repo.FindByEmail("test.user@blah.com");
            user.CompanyAssociations.Add(new CompanyUserAssoc() 
                { 
                    User = user,
                    Company = cRepo.GetById(1)
                });
            repo.AddOrUpdate(user);

            //session.Transaction.Commit();
        }

用户、公司和 CompanyUserAssoc 之间的关系相当直接:

对于公司:

HasMany<CompanyUserAssoc>(x => x.UserAssociations).KeyColumn("User_id");

对于用户:

HasMany<CompanyUserAssoc>(x => x.CompanyAssociations).KeyColumn("Company_id")

对于关联类本身:

References(x => x.Company).UniqueKey("CompanyId_UserId");
References(x => x.User).UniqueKey("CompanyId_UserId");

现在这就是我感到困惑的地方。请注意,在我的初始代码中,开始和提交 trans 调用已被注释掉。这实际上意味着代码将起作用!CompanyUserAssoc 已创建并正确引用了 id 为 1 的用户和公司。太好了!

但是......可悲的是,当我把它放在一个交易中时,我得到了这个错误:

{"The UPDATE statement conflicted with the FOREIGN KEY constraint \"FK3C47859753A62C6E\". The conflict occurred in database \"xxxx\", table \"dbo.Company\", column 'Id'.\r\nThe statement has been terminated."}

但为什么?那是我的问题。我在分析器中看到的是它这样做:

exec sp_executesql N'UPDATE [CompanyUserAssoc] SET Company_id = null WHERE Company_id = @p0',N'@p0 int',@p0=1

等等……什么?无效的?为什么将公司ID设置为null?为什么它只在交易中这样做?我的 Nhibernate 映射有什么“错误”?

4

2 回答 2

0

由于这两个集合都映射为非反向(默认)并且 Company 集合没有用户,因此它将发出该更新以清除链接表。您可以尝试将其设置UserAssociations为反向吗?或者,当涉及到显式链接表时,我通常会做的是将HasManys 都设置为反向并直接使用链接表。

于 2013-02-01T19:56:56.347 回答
0

这到底是一条红鲱鱼,一条我已经开始鄙视的鱼。在我匆忙和依赖智能感知的过程中,我没有注意到 Company 的 UserAssocations 属性不是 IList 而是 IList!是的,我愚蠢地选择了 Nhib 地图类而不是域类。这很奇怪,这并没有像您期望的那样出错,并且在没有事务的情况下工作,但是为什么呢?

好吧 - Nhib 能够插入 assoc 条目,但随后认为它需要使用它已经插入的 id 更新同一个表(因为它以某种方式将其视为不同的实体?)。当我使用该类型时,我会预料到地图类本身会出现编译错误,但没有。并且没有事务,生成的 sql 就可以工作。

我会更多地调查原因,但我回答这个只是为了强调一个罕见且愚蠢的错误,如果错过,可能会导致大量调查。

于 2013-02-03T17:06:08.117 回答