0

请原谅这个尴尬的标题。我不完全确定如何表达它

我有一个实体,我们称之为AA每周从电子表格中提取,然后存储在表格中。电子表格是累积的,因为从 6 周前提取的数据包含在 1 周前的电子表格中。

现在,有时这些数据是相同的,不需要更改。有时它需要改变。我想让主表充满最新的数据。也就是说,随着实体的更新,过时的实体将被删除,并在其位置插入较新的实体。

当一个A实体发生变化时,我创建一个Conflict, 这样它Conflict就有一个 Guid、一个冲突发现的 DateTime、一个注释和一个旧实体的副本(以便我们可以看到发生了什么变化等等),以及相关的冲突。相关的冲突工作正常,但是我想知道如何保留旧实体。

我可以做一个组件映射,但这只会让表格爆炸,我相信我可以以更“漂亮”的方式做到这一点。

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表没有任何与冲突相关的内容(只是实际属性)。

那么如何映射旧实体呢?我是否必须为旧A实体生成一个新类,或者有什么方法可以在 Fluent/NHibernate 中做到这一点?

4

1 回答 1

0

assuming you have classes like this

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; }
}

then mappings with

  • removed Inverse because there is no backreference in Conflict like RelatesTo
  • Cascade.None() on Conflicts because deleting IssueVersion should not automaticly delete all Conflicts of the Issue
  • renamed some columns for clarity
  • a second mapping for archived Issues


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 would create a table which are a exact copy of the Issue table. and using it should be easy

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);

querying old Issues would be

var oldIssueVersions = session.CreateCriteria<Issue>("ArchivedIssues")
    .List<Issue>();
于 2013-02-20T07:44:28.977 回答