2012-03-15 76 views
0

我想用標籤保存圖書。我的問題是,兩本書中的相同標籤被保存兩次。NHibernate多對多保存重複數據

我的課:

public class Book 
{ 
    public virtual long ID { get; set; } 
    public virtual string Title { get; set; } 
    protected ICollection<Tag> _Tags = new List<Tag>(); 
    public virtual ICollection<Tag> Tags { get { return _Tags; } set { _Tags = value; } } 
} 

public class Tag: IComparable 
{ 
    public virtual long ID { get; set; } 
    public virtual string Name { get; set; } 

    public override string ToString() { return Name; } 
    public virtual int CompareTo(object obj) { return string.Compare(Name, ((Tag)obj).Name); } 
    public override int GetHashCode() { return Name.GetHashCode(); } 
    public override bool Equals(object obj) { return Name.Equals(((Tag)obj).Name); } 
} 

的映射是:

<class name="Book" table="Books"> 
<id name="ID"> 
    <generator class="identity"/> 
</id> 
<property name="Title"/> 
<set name="Tags" table="BookTags" cascade="all-delete-orphan"> 
    <key column ="BookID" /> 
    <many-to-many class="Tag" column="TagID" /> 
</set> 
</class> 

<class name="Tag" table="Tags"> 
<id name="ID"> 
    <generator class="identity"/> 
</id> 
<property name="Name"/> 
</class> 

我的代碼是:

Book book; 

book = new Book() { Title = "C#" }; 
book.Tags.Add(new Tag() { Name = "Programming" }); 
book.Tags.Add(new Tag() { Name = "Computer" }); 
PersistenceManager.Save(book); 

book = new Book() { Title = "Android" }; 
book.Tags.Add(new Tag() { Name = "OS" }); 
book.Tags.Add(new Tag() { Name = "Computer" }); 
PersistenceManager.Save(book); 

保存後,我想在表中具有三個標籤標籤:編程,計算機和Android。實際上,電腦被保存了兩次。原因是因爲我使用兩個具有相同值的不同參考。

我厭倦了重寫標記類中的CompareTo,GetHashCode和Equals,但沒有成功。如果不同引用的值相同,是否有可能防止將值保存兩次?

回答

2

您無法用名稱「計算機」創建兩次標籤的新實例,並且希望爲每個值生成相同的標識。你的代碼中沒有任何東西告訴nhibernate這兩個標籤是相同的。

嘗試:

var computerTag = new Tag() { Name = "Computer" }); 

Book book; 
book = new Book() { Title = "C#" }; 
book.Tags.Add(new Tag() { Name = "Programming" }); 
book.Tags.Add(computerTag); 
PersistenceManager.Save(book); 

//At this point (due to your mapping, the computerTag has been persisted 
//and it will have an ID. 

book = new Book() { Title = "Android" }; 
book.Tags.Add(new Tag() { Name = "OS" }); 
book.Tags.Add(computerTag); 
PersistenceManager.Save(book);