我最近需要使用Colectica SDK for DDI的脚本更新一百多个概念项目,并且我需要将这些更新传播到具有已知根项目项目的集合中的所有位置。这意味着每个引用旧版本概念的项目都需要更新以引用新版本。这将创建一个新版本的引用项,该版本需要类似地在集合内传播其更新。
我尝试过的最佳解决方案使用 的实现IVersionableVisitor
来更新过时的引用,根据需要将项目标记为脏。此时,DirtyItemGatherer
可以使用访问者来收集和发布项目。这不会一次性完成,但希望它可以运行直到不再需要更新项目。
internal class ReferencedVersionUpdaterVisitor : IVersionableVisitor
{
public ReferencedVersionUpdaterVisitor(WcfRepositoryClient repositoryClient)
{
this.RepositoryClient = repositoryClient;
this.VisitedLog = new Dictionary<Tuple<Guid, string>,bool>();
this.Context = new List<IVersionable>();
}
private WcfRepositoryClient RepositoryClient { get; set; }
private Dictionary<Tuple<Guid, string>, bool> VisitedLog { get; set; }
public bool HaveVisited(IdentifierTriple id)
{
var logId = Tuple.Create(id.Identifier, id.AgencyId);
return this.VisitedLog.ContainsKey(logId) && this.VisitedLog[logId];
}
public void RegisterVisit(IdentifierTriple id)
{
this.VisitedLog[Tuple.Create(id.Identifier, id.AgencyId)] = true;
}
private List<IVersionable> Context { get; set; }
public void BeginVisitItem(IVersionable item)
{
if (!this.HaveVisited(item.CompositeId) &&
!this.Context.Any(contextItem => contextItem.CompositeId.Identifier.Equals(item.CompositeId.Identifier) && contextItem.CompositeId.AgencyId.Equals(item.CompositeId.AgencyId)))
{
if (!item.IsPopulated)
{
var previousVersion = item.Version;
this.RepositoryClient.PopulateItem(item, true, ChildReferenceProcessing.Instantiate);
if (previousVersion != item.Version)
{
item.IsDirty = true;
}
}
this.Context.Add(item);
}
}
public void EndVisitItem(IVersionable item)
{
if (!this.HaveVisited(item.CompositeId))
{
this.Context.Remove(item);
this.RegisterVisit(item.CompositeId);
}
}
}
不幸的是,它不起作用;每次通过都会找到相同的项目,因为该集合仍然包含引用旧版本子项目的父项目。我已经将思想和精力投入到调整这种方法的想法中,例如修改项目EndVisitItem()
以在向上修改的过程中进行修改,但这并没有解决真正的问题。
我认为基本问题是访问者在遍历集合时需要修改父项。由于这是一个图表,因此实际上并没有父项,而是我碰巧用来访问当前节点的引用项。我尝试使用该Context
属性记录此内容,但其内容似乎并不总是符合我的预期,即上下文列表中的最后一项是“父”引用项。
在 Colectica Designer 中,通过内部使用 Navigator 结构解决了这个问题,遗憾的是我在 Colectica SDK 中看不到它。此外,虽然 Colectica Designer 的基于 Navigator 的解决方案性能非常好,但由于多次往返于BeginVisitItem()
. 这让我觉得好像我可能做错了。有没有更好的方法使用 Colectica SDK 提供的工具来解决这个问题?
我还应该注意,我知道在所有子项目上填充最新的能力,但是从那里,定位所有脏项目、碰撞它们的版本、保存它们和传播更新的问题似乎变成了同样的问题我已经在尝试解决了。
我还想补充一点,将根集中的所有内容更新到最新版本,而不仅仅是那些概念和相关项目,这将是非常好的,事实上,可能是首选。