我正在构建一个“了解 NHibernate 项目”。
我的单元测试 (nunit) 为存储库层提供与普通 mvc 站点相同的配置,但使用“SQLiteConfiguration.Standard.InMemory()”而不是“MsSqlConfiguration.MsSql2008”。我希望我可以以完全相同的方式使用流利的休眠和自动映射,但有一个用于测试的快速内存数据库和一个用于应用程序的真实数据库。
在存储库构造函数中,它为所有查询创建 Session 对象以供使用,并实现 IDisposable ,这将确保正确处理会话。例如,保存文章方法如下所示:
public void SaveArticle(Article article)
{
Session.SaveOrUpdate(article);
Session.Flush();
}
到目前为止,MVC 站点似乎一切正常,我的测试也通过了。我想我遇到了一个问题,这一定是我的设计问题。
到目前为止,我有两个对象:
class Article
{
public virtual int Id {get; set; }
public virtual IList<Tag> Tags {get; set; }
}
class Tag
{
public virtual int Id {get; set; }
public virtual string Text {get; set; }
}
我只希望数据库存储每个标签的一个实例。如此多的文章可以使用相同的标签。所以我写了这个测试:
[Test]
public void TestDeletingTagWillNotDeleteOthersTagV2()
{
Article article = new Article();
article.Tags.Add(new Tag { Text = "C#" });
article.Tags.Add(new Tag { Text = "VB" });
Service.SaveArticle(article);
Article article2 = new Article();
article2.Tags.Add(new Tag { Text = "C#" });
Service.SaveArticle(article2);
Guid article1Id = article.Id;
Guid article2Id = article2.Id;
article = null;
article2 = null;
Article article3 = Service.GetArticle(article1Id);
Article article4 = Service.GetArticle(article2Id);
Assert.AreEqual(2, article3.Tags.Count);
Assert.AreEqual(1, article4.Tags.Count);
Assert.AreEqual(2, Service.Tags.Count);
article3.Tags.RemoveAt(0);
Service.SaveArticle(article3);
Article article5 = Service.GetArticle(article1Id);
Article article6 = Service.GetArticle(article2Id);
Assert.AreEqual(1, article5.Tags.Count);
Assert.AreEqual(1, article6.Tags.Count);
Assert.AreEqual(2, Service.Tags.Count);
}
这个测试通过了,但我相信它应该会失败。(当您运行 MVC 站点时,即第一篇文章只有一个标签,“VB”而不是“C#”和“VB”。
我相信它是因为会话仍然开放,所以休眠仍然保留所有内容并记住曾经发生过的事情。
我的主要问题是如何使用内存数据库进行测试?如何确保在保存和删除共享标签后,文章仍然具有应有的内容?
它创建的表结构是,(我觉得不对,应该有一个链接表):
Article:
Id (PK, uniqueid, not null)
...........
Tag
Id (PK, uniqueid, not null)
Text (nvarchar, null)
Article_id (FK, uniqueid, null)
不知道如何使用流利的自动映射来设置链接表,以便一个标签可以跨多篇文章共享,一篇文章可以有多个标签
相信我找到了如何确保标签和文章有一个链接表:
configuration.Mappings(m => m.AutoMappings.Add((AutoMap.AssemblyOf<Article>())
.Override<Article>(map => map.IgnoreProperty(x => x.IsPublished))
.Override<Article>(map => map.HasManyToMany(a => a.Tags).Cascade.All())
.Conventions.Add(DefaultCascade.All()))