流畅的NHibernate映射 - 将n-m转换为1-n关系

时间:2014-08-15 20:30:12

标签: c# nhibernate fluent-nhibernate

我创建了三个实体:

public class Company : EntityBase
{
   some properties
   public virtual IList<UserCompanyAttachment> AttachedUsers {get; set;}

   public virtual void AttachUser(User userToAttach)
   {
       var userCompanyAttachment = new UserCompanyAttachment()
       {
           AttachedCompany = this,
           AttachedUser = userToAttach
       }
       AttachedUsers.Add(userCompanyAttachment);
   }
}

public class User : EntityBase
{
   some properties
   public virtual IList<UserCompanyAttachment> AttachedCompanies {get; set;}

   public virtual void AttachCompany(Company companyToAttach)
   {
       var userCompanyAttachment = new UserCompanyAttachment()
       {
           AttachedCompany = companyToAttach,
           AttachedUser = this
       }
       AttachedCompanies.Add(userCompanyAttachment);
   }
}

public class UserCompanyAttachment : EntityBase
{
    public virtual User AttachedUser { get; set; }
    public virtual Company AttachedCompany { get; set; }
     .. some properties ..
}

我与流利的人建立了关系 - 公司和用户的映射得到了:

HasMany(x => x.AttachedCompanies/Users).Inverse.Cascade.All();

UserCompanyAttachemnt映射是:

References(x => x.AttachedUser);
References(x => x.AttachedCompany);

我没有创建正常的,多对多关系的原因是因为我需要存储关于附件的信息。 (没有冗余,因为在这两种情况下,数据库中都存在物理第三个表)但是当我尝试实例时,附加用companyObject.AttachUser(newUser)更改的用户仅在company.AttachedUsers上可见 - 但在newUser.AttachedCompanies中不可见}。有没有办法用一些映射来推动变化?为什么会失败?

编辑:添加单元测试失败

    [Test]
    public void CanCorrectlyMapUserCompanyAttachmentWhenAddedByUser()
    {
        var testUser = new User() { PasswordHash = "pp", PasswordSalt = "qq", Username = "user" };
        var testCompany = new Company()
        {
            Address = new Address() { City = "q" },
            AgentName = "tt",
            Comments = "z",
            CompanyName = "g",
            MailAddress = "@@",
            NIP = 231123
        };

        DbSession.Save(testUser);
        DbSession.Save(testCompany);
        testUser.AttachCompany(testCompany);
        DbSession.Flush();

        var addedAttachment = DbSession.Get<UserCompanyAttachment>(1);

        User addedUser = DbSession.Get<User>(1);
        Company addedCompany = DbSession.Get<Company>(1);

        Assert.AreEqual(addedAttachment .AttachedUser.Id, 1);
        Assert.AreEqual(addedAttachment .AttachedCompany.Id, 1);
        Assert.IsTrue(addedUser.AttachedCompanies.Contains(addedAttachment));
        Assert.IsTrue(addedCompany.AttachedUsers.Contains(addedAttachment)); // here it fails
    }

1 个答案:

答案 0 :(得分:1)

这里的问题是:

  • 我们在 C#将配对实例UserCompanyAttachment分配到AttachedUsers集合Company实例{ {1}})
  • 我们做了让NHibernate从DB重新加载所有三个 - 刚刚创建的实例。仍然从会话返回的所有对象 - 它的第一级缓存。

所以,我们能做的是:

1)同时将配对对象分配到公司的集合testCompany中。但我不会那么复杂。因为我们的操作应该始终是读或写。每个人都应该拥有自己独立/独特的ISession。 (即不共享第一级缓存)

2)首选的方法是将它留在NHibernate上。这个很棒的工具将按照我们的预期填充所有集合。只需要允许从DB重新加载所有内容。怎么样?只需一行代码:

AttachedUsers

这个简单的陈述: // creation of all the stuff in the unit test ... ... DbSession.Flush(); // new line - essential setting - clearing the first level cache DbSession.Clear(); // the test continues as it was... passing all assertion ... 是成功的关键。为什么?因为NHibernate现在可以完全访问基于DB数据的正确实例化...而不是&#34;弱设置关系&#34;在我们的C#中。

这将是首选方式:拆分写入和读取==让NHibernate填充我们的对象,它将正确完成...