【发布时间】:2018-11-23 17:22:17
【问题描述】:
我的任务是通过一项服务双向同步两个邮箱中的联系人文件夹。 请多多包涵,因为这是我第一次在 C# 中使用 EWS。
为了唯一标识项目并跟踪同步更改,我将SyncFolderHierarchy() 用于子文件夹,SyncFolderItems() 用于每个子文件夹中的项目,同时跟踪同步状态。
由于文件夹/项目 ID 依赖于邮箱、初始同步以及创建操作,我通过 Item.SetExtendedProperty() 使用扩展属性标记同步项目
这确实很好,但我遇到了一个警告。
当用户在 Outlook 中复制和粘贴文件夹或联系人时,它还会复制唯一 ID(扩展属性),使其不再唯一。 在这种情况下,我现在在一个邮箱中有两个具有相同“唯一”ID 的项目,并且现在该项目有一个模棱两可的匹配项。
基本上:
-
SyncFolderItems()被调用,同步状态被保存 - 如果项目没有唯一 ID,则使用唯一 ID 进行标记
- 用户复制并粘贴项目
-
SyncFolderItems()被调用(与之前的同步状态),为用户复制的项目返回一个Create事件 - 创建的项目已有唯一 ID
现在,有人可能会争辩说只是在创建事件中覆盖项目的唯一 ID。
但是,这会导致以下问题:
当我将邮箱 A 中的新项目同步到邮箱 B 时,我还创建了一个项目。
现在调用邮箱 A 上的 SyncFolderItems() 后,我还会为我自己的项目检索一个 Create 事件,在这种情况下,它已经合法地分配了一个不能被覆盖的唯一 ID。
我基本上看到了两种选择:
以某种方式阻止此扩展属性可复制
-
防止 EWS 为我自己创建的项目发送创建。 我知道我可以在
SyncFolderItems()调用中忽略 ItemID,但我不确定我应该如何跟踪调用中的项目 ID,因为它们可能会根据 documentation 发生变化
是否有人对如何以不同方式处理此问题或实施任一选项有任何建议?
【问题讨论】:
-
两个数据库之间的直接同步要求密钥实际上是唯一的。正如你所说,他们没有正确地做到这一点。所以你需要一个第三个数据库。某些文件格式或其他您和仅您提供主键的文件格式。这样您就可以控制并保持每个键实际上是唯一的。
-
是的,我正在考虑在 sqlite 中进行跟踪。但是,在复制时,Exchange 仍会复制我分配给项目的唯一键,或者在数据库术语中,违反了该约束。因此,将密钥保留在第三位仍然会导致匹配不明确:/
-
@Christopher 澄清一下:您的意思是保留所有发布过的同步 ID,并且当更改事件带有从未见过的同步 ID 时,忽略它?我目前正在考虑注意事项,可能会尝试一下......
-
我的意思是忽略 Exchange 中的密钥。它不可靠,而且可能永远不会。您甚至可能会误用一个并非用于主键的字段。有第三个数据库。让 it 成为两个端点状态的权威。
-
@Christopher 是的,好的,所以让我问一下:似乎不能保证 ItemID/FolderID 保持不变。因此,如果我将其存储在主数据库中,如何在
SyncFolderItems()调用中将项目与主数据库匹配? docs.microsoft.com/en-us/previous-versions/office/developer/… 的代码示例仅提及“Todo: Update / Delete / ... item on client”和ic.ItemId.UniqueId:这里的 ItemID(或 uniqueID)是否保证与之前看到的内容匹配?
标签: c# exchangewebservices extended-properties