2013-02-19 55 views
0

請原諒尷尬的標題。我不完全確定如何將其詞組化我應該如何將一個實體映射到兩個表格

我有一個實體,我們稱之爲A。每週從電子表格中拉出A,然後存儲在表格中。電子表格是累積的,因爲從6周前開始的數據包含在1周前的電子表格中。

現在,有時這些數據將是相同的,不需要改變。有時候需要改變。我想讓主表充滿最新的數據。也就是說,隨着實體更新,過時的實體被刪除,並且新的實體被插入。

A實體發生了變化,我創建了一個Conflict,使得該Conflict都有一個GUID,衝突發現的日期時間,註釋和老實體的副本(這樣我們就可以看到發生了什麼變化等等)以及相關的衝突。相關的衝突工作正常,但我想知道如何堅持舊的實體。

我可以做一個組件映射,但這只是爆炸表,我相信我可以以更「漂亮」的方式做到這一點。

Conflict映射如下:

public class ConflictAMapping : ClassMap<Conflict<A>> 
{ 
    public ConflictAMapping() 
    { 
     Id(c => c.Guid); 
     Map(c => c.DateOfConflict); 
     Map(c => c.Comment); 
     HasMany(c => c.RelatedConflicts) 
      .KeyColumn("ConflictKey") 
      .Inverse() 
      .Cascade.All() 
      .Table("RelatedConflicts"); 
     References<A>(c => c.OriginalEntity) 
      .Column("FK_IssueNumber") 
      .Cascade.All(); 
    } 
} 

而且我A映射

public class GSFEntityMapping : ClassMap<GSFEntity> 
{ 
    public GSFEntityMapping() 
    { 

    ... unrelated properties blah blah ... 
     HasMany(g => g.Conflicts).KeyColumn("theKey") 
      .Table("Conflicts") 
      .AsBag().Cascade.All() 
    } 
} 

Conflict表看起來像這樣:

Guid|DateOfConflict|CommentFK_IssueNumber|ConflictKey|theKey 

A表沒有任何與其中的衝突有關的東西(j實際屬性)。

那麼如何映射舊的實體?我是否必須爲舊的A實體生成一個新類,或者有什麼方法可以在Fluent/NHibernate中執行此操作?

回答

0

假設你有類這樣

class Issue 
{ 
    public virtual int Id { get; protected set; } 
    public virtual string Key { get; set; } // same for all versions of the issue 
    public virtual DateTime Created { get; set; } 
} 

class Conflict<T> 
{ 
    public virtual Guid Id { get; protected set; } 
    public virtual T OriginalEntity { get; set; } 
    public virtual DateTime DateOfConflict { get; set; } 
    public virtual string Comment { get; set; } 
    public virtual string IssueKey { get; set; } 
    public virtual ICollection<Conflict<T>> RelatedConflicts { get; protected set; } 
} 

然後用

  • 去除逆映射,因爲在像RelatesTo衝突)的衝突沒有反向引用
  • Cascade.None(因爲刪除IssueVersion不應該自動刪除所有問題的衝突
  • 爲了清晰而重新命名了一些列
  • 第二映射用於存檔的問題


public class ConflictAMapping : ClassMap<Conflict<Issue>> 
{ 
    public ConflictAMapping() 
    { 
     Id(c => c.Id).GeneratedBy.Assigned(); 
     Map(c => c.DateOfConflict); 
     Map(c => c.Comment); 
     HasMany(c => c.RelatedConflicts) 
      .KeyColumn("RelatedToConflict") 
      .Cascade.All(); 
     References(c => c.OriginalEntity) 
      .EntityName("ArchivedIssue") 
      .Column("FK_Issue_id") 
      .Cascade.All(); 
    } 
} 

public class IssueMapping : ClassMap<Issue> 
{ 
    public IssueMapping() 
    { 
     Id(c => c.Id).GeneratedBy.Assigned(); 
     Map(c => c.Key); 
     Map(c => c.Created); 
     HasMany(g => g.Conflicts) 
      .KeyColumn("IssueKey") 
      .PropertyRef("Key") 
      .Cascade.None(); 
    } 
} 

public class ArchivedIssueMapping : IssueMapping 
{ 
    public ArchivedIssueMapping() 
    { 
     Table("ArchivedIssues"); 
     EntityName("ArchivedIssue"); 
    } 
} 

ArchivedIssues將創建一個表,該表是問題表的精確副本。並使用它應該很容易

var oldIssueVersion = session.Get<Issue>(newIssueVersion.Id); 
session.Delete(oldIssueVersion); 

var conflict = new Conflict<Issue>() { Id = Guid.NewGuid(), IssueKey = oldIssueVersion.Key, OriginalEntity = oldIssueVersion, DateOfConflict = DateTime.Now }; 
session.Save(conflict); 
session.Save(newIssueVersion); 

查詢老問題將

var oldIssueVersions = session.CreateCriteria<Issue>("ArchivedIssues") 
    .List<Issue>(); 
相關問題