使用实体框架在SQL Express服务器之间将数据与标识列同步

问题描述 投票:2回答:1

我设计了一个数据库,该数据库的MDF文件将被复制到远程办公室,因此基本上,我将使用相同的方案使用不同的数据库。 但是,这些数据库中的某些表将必须包含相同的数据。 首先,我很高兴,因为我知道使用每个表中的RowVersion列来同步它们很容易,但是后来我记得这些表中的主键列(名为“ ID”的列)也是标识列。 因此,我不知道如何以相同的方式同步它们。 具有相同的ID和所有内容。 我也是通过实体框架(位于SQL Server 2008 R2 Express和.NET Framework 4 WCF服务之间)进行此操作的。 有什么线索吗? 请注意,这是一种单向同步,远程办公室需要从主数据库复制这些表,但是它们不能修改它们并写回更改。

原始线程从此处开始: http : //social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/e5f89bac-959c-490a-befc-a80d5aa9a9a5/,但我尚未提出解决方案。 如果看一下我链接到的线程,您将看到建议的解决方案是将记录从主数据库上下文附加到客户端数据库上下文,并调用“ ApplyCurrentValues”方法更新客户端数据库。 但是,我得出的结论是,由于以下原因,它根本不起作用:

  1. 来自两个上下文的数据之间的不同EntityKey值。 如果记录的EntityKey与上下文不对应,则不能将记录附加到上下文。 为了解决此问题,我必须使用AutoMapper将对象从mainDB转换为clientDB的对象,并在将记录附加到clientDB上下文之前手动设置EntityKey。
  2. 如果要添加新记录(如果mainDB中存在一个记录,而clientDB中不存在),则不能使用Attach。 如果您要附加的记录在存储中不存在,EF会将异常抛出给您。
  3. 如果要添加新记录,则必须使用AddObject,但这意味着EntityKey是自动生成的,您将无法控制Identity列。 如果尝试在添加新记录之前手动设置EntityKey,则EF会向您抛出异常。

因此,问题是,如何使用EntityFramework将数据从主数据库复制到客户端数据库?

entity-framework synchronization sql-server-express identity n-tier-architecture
1个回答
1
投票

我们最近实现了此解决方案,但是我们的数据库非常简单,我们只有一个元服务器(我们称其为元服务器,因为它是仅包含身份的服务器),还有数据服务器。 我们有三个数据服务器执行三种方式的同步。 现在,最初我们只有三台服务器,但是插入新的ID是个问题,我们也不想使用GUID,因为它不是人类可读的。

因此,我们引入了IdentityServer(称为MetaServer)的概念,该概念承载一个简单的Web服务和简单​​的数据库,该数据库由仅包含身份的表组成,哈希和LastUpdate,哈希和LastUpdate用于验证同步。

例如,Meta Server上有以下两个表,

Tickets
   TicketID (Primary Key,Identity)
   LastUpdate (DateTime)
   Hash (Hash of Ticket)

Tasks
   TaskID (Primary Key, Identity)
   LastUpdate (DateTime)
   Hash (Hash of Task)

现在,数据服务器将包含以下票证,

Tickets
   TicketID (Primary Key)
   Subject
   Message
   ... 
   ...
Tasks
   TaskID (Primary Key) 
   Subject
   Message
   ...
   ...

我们在ObjectContext上的Save方法如下所示,

Task task = new Task();
task.TaskID = MetaService.GetNewTaskID();


...
...
// following is save method, checking insert or update, as it is used in 
//synchronization, thats why i wrote it like this
void SaveTask(Task task){
   Task copy = ObjectContext.Tasks.FirstOrDefault(x=>x.TaskID==task.TaskID);
   if(copy==null){
      copy = new Task();
      ObjectContext.Tasks.AddObject(copy);
   }
   CloneData(task,copy);
   ObjectContext.SaveChanges();
}

要执行同步,我建议添加一个这样的表,该表将保存Meta Server(主服务器)中的每个更改

Changes
  ChangeID
  ChangeType = Insert,Update,Delete
  ChangeTable
  ChangeKey
  ChangeTime

然后每个数据服务器都可以从Meta Server中读取并更新更改...

© www.soinside.com 2019 - 2024. All rights reserved.