2013-02-19 56 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>(); 
相关问题