0
我有以下兩個實體,用自己的映射:許多一對多和級聯:與實體問題缺失
public class VideoCategory : BaseEntity<VideoCategory>
{
private readonly Iesi.Collections.Generic.ISet<VideoFolder> folders = new HashedSet<VideoFolder>();
public VideoCategory()
{
}
public VideoCategory(string name)
{
Name = name;
}
public string Name { get; set; }
public IEnumerable<VideoFolder> Folders { get { return folders; } }
public void AddFolder(VideoFolder videoFolder)
{
Contract.Requires(videoFolder != null);
if (folders.Contains(videoFolder))
return;
folders.Add(videoFolder);
videoFolder.AddCategory(this);
}
public void RemoveFolder(VideoFolder videoFolder)
{
folders.Remove(videoFolder);
videoFolder.RemoveCategory(this);
}
public void ClearFolders()
{
folders.ForEach(f => f.RemoveCategory(this));
folders.Clear();
}
}
public class VideoFolder : BaseEntity<VideoFolder>
{
private readonly Iesi.Collections.Generic.ISet<VideoCategory> categories = new HashedSet<VideoCategory>();
public VideoFolder()
{
}
public VideoFolder(string path)
{
Path = path;
}
public string Path { get; set; }
public string Name { get; private set; }
public IEnumerable<VideoCategory> Categories { get { return categories; } }
protected internal void AddCategory(VideoCategory videoCategory)
{
Contract.Requires(videoCategory != null);
categories.Add(videoCategory);
}
protected internal void RemoveCategory(VideoCategory videoCategory)
{
categories.Remove(videoCategory);
}
}
public class VideoCategoryMap : ClassMap<VideoCategory>
{
public VideoCategoryMap()
{
Table("VideoCategories");
Id(cat => cat.Id)
.GeneratedBy.Native();
Map(cat => cat.Name)
.Unique()
.Not.Nullable();
HasManyToMany<VideoFolder>(Reveal.Member<VideoCategory>("folders"))
.Access.CamelCaseField()
.AsSet()
.Inverse()
.Cascade.AllDeleteOrphan();
}
}
public class VideoFolderMap : ClassMap<VideoFolder>
{
public VideoFolderMap()
{
Table("VideoFolders");
Id(folder => folder.Id)
.GeneratedBy.Native();
Map(folder => folder.Path)
.Not.Nullable();
HasManyToMany<VideoCategory>(Reveal.Member<VideoFolder>("categories"))
.Access.CamelCaseField()
.AsSet();
}
}
我有這2個單元測試:
[Fact]
public void DeletingVideocategory_DeletesVideoFolders()
{
object id;
using (ISession session = SessionFactory.OpenSession())
{
var categ = new VideoCategory("Foo");
var folder = new VideoFolder("D:\\Foo");
categ.AddFolder(folder);
id = session.Save(categ);
session.Flush();
}
using (ISession session = SessionFactory.OpenSession())
{
var category = session.Get<VideoCategory>(id);
category.ClearFolders();
session.Delete(category);
session.Flush();
Assert.Equal(0, session.QueryOver<VideoFolder>().RowCount());
}
}
[Fact]
public void DeletingVideocategory_DoesntDeleteVideoFoldersOwned_ByOtherCategories()
{
object id;
object id2;
using (ISession session = SessionFactory.OpenSession())
{
var categ = new VideoCategory("Foo");
var categ2 = new VideoCategory("Bar");
var folder = new VideoFolder("D:\\Foo");
categ.AddFolder(folder);
categ2.AddFolder(folder);
id = session.Save(categ);
id2 = session.Save(categ2);
session.Flush();
}
using (ISession session = SessionFactory.OpenSession())
{
var category = session.Get<VideoCategory>(id);
category.ClearFolders();
session.Delete(category);
session.Flush();
Assert.Equal(1, session.QueryOver<VideoFolder>().RowCount());
Assert.Equal(1, session.Get<VideoCategory>(id2).Folders.Count());
}
}
第一一個成功,但不是第二個聲明,視頻文件夾被刪除,而它仍然與其餘的視頻類別相關聯。
這裏是第二測試的SQL輸出:
INSERT INTO VideoCategories (Name) VALUES (@p0); select last_insert_rowid();@p0 = 'Foo' [Type: String (0)]
INSERT INTO VideoFolders (Path) VALUES (@p0); select last_insert_rowid();@p0 = 'D:\Foo' [Type: String (0)]
INSERT INTO VideoCategories (Name) VALUES (@p0); select last_insert_rowid();@p0 = 'Bar' [Type: String (0)]
INSERT INTO CategoriesToFolders (VideoFolder_id, VideoCategory_id) VALUES (@p0, @p1);@p0 = 1 [Type: Int32 (0)], @p1 = 1 [Type: Int32 (0)]
INSERT INTO CategoriesToFolders (VideoFolder_id, VideoCategory_id) VALUES (@p0, @p1);@p0 = 1 [Type: Int32 (0)], @p1 = 2 [Type: Int32 (0)]
SELECT videocateg0_.Id as Id10_0_, videocateg0_.Name as Name10_0_ FROM VideoCategories videocateg0_ WHERE [email protected];@p0 = 1 [Type: Int32 (0)]
SELECT folders0_.VideoCategory_id as VideoCat1_1_, folders0_.VideoFolder_id as VideoFol2_1_, videofolde1_.Id as Id13_0_, videofolde1_.Path as Path13_0_ FROM CategoriesToFolders folders0_ left outer join VideoFolders videofolde1_ on folders0_.VideoFolder_id=videofolde1_.Id WHERE [email protected];@p0 = 1 [Type: Int32 (0)]
SELECT categories0_.VideoFolder_id as VideoFol2_1_, categories0_.VideoCategory_id as VideoCat1_1_, videocateg1_.Id as Id10_0_, videocateg1_.Name as Name10_0_ FROM CategoriesToFolders categories0_ left outer join VideoCategories videocateg1_ on categories0_.VideoCategory_id=videocateg1_.Id WHERE [email protected];@p0 = 1 [Type: Int32 (0)]
SELECT videos0_.VideoFolder_id as VideoFol3_1_, videos0_.Id as Id1_, videos0_.Id as Id12_0_, videos0_.Path as Path12_0_ FROM VideoFiles videos0_ WHERE [email protected];@p0 = 1 [Type: Int32 (0)]
DELETE FROM CategoriesToFolders WHERE VideoFolder_id = @p0;@p0 = 1 [Type: Int32 (0)]
DELETE FROM VideoFolders WHERE Id = @p0;@p0 = 1 [Type: Int32 (0)]
DELETE FROM VideoCategories WHERE Id = @p0;@p0 = 1 [Type: Int32 (0)]
SELECT count(*) as y0_ FROM VideoFolders this_
如果更改映射,以及修改在Cascade.AllDeleteOrphan VideoCategoryMap,第二測試成功,而第一失敗,因爲孤立視頻文件夾不會被刪除。
如何使兩種測試都成功?
在此先感謝
邁克
第二次單元測試的問題到底是什麼?兩個斷言中的哪一個失敗? – Aaronontheweb 2010-12-07 17:41:57
在第二個測試中,這是第一個失敗的斷言。我正在更新問題 – Mike 2010-12-07 18:53:01