C# WPF Entity Framework 6 同步数据库
Posted
技术标签:
【中文标题】C# WPF Entity Framework 6 同步数据库【英文标题】:C# WPF Entity Framework 6 Synchronization databases 【发布时间】:2015-06-18 01:07:46 【问题描述】:场景:
我有两个 mysql 数据库:
-
大主数据库
小客户端数据库
示例表:
大数据库用户:
文字用户名
int id varchar 登录 varchar 密码 ...更多字段客户端数据库用户
int id int UNIQUE api_id (来自 master 的 id) varchar 登录 varchar 密码问题: 我需要同步数据库,但我不知道如何以最好的方式做到这一点。我读过this question,但它已经很老了,不包括我的情况。 我通过 REST API 与主数据库通信,直接连接不是选项。
我的同步算法
将数据从 REST API(例如 /api/users/ )下载并反序列化到 ApiUser 对象列表 公共类 ApiUser 内部标识; 字符串登录; 字符串密码; 公共类用户 内部标识; 诠释 api_id; 字符串登录; 字符串密码; 遍历 Apiuser 列表 如果存在具有 ApiUser.id 的实体,则覆盖所有字段 否则创建新实体 保存更改我的代码:
公共无效同步用户(列表 ApiUsers) 使用 (var db = new dbEntities()) ApiUsers.ForEach(apiUser => var dbUser = db.client .Where(c => c.api_id == apiUser.id) .SingleOrDefault(); 如果(dbUser == null) var userObj = 新用户() api_id = apiUser.id, 登录 = apiUser.login, 密码 = apiUser.password ; db.client.Add(userObj); 别的 dbUser.api_id = apiUser.id, dbUser.login = apiUser.login, dbUser.password = apiUser.password ); db.SaveChanges();问题: 如何做得更好?我对从主数据库中删除的实体有疑问,我的算法不涵盖这种情况。
【问题讨论】:
除了从数据库中删除用户之外,是否可以有一个标志,如果用户被删除,则可以将其标记为 true,这样您的代码就不会再次重新创建用户? 【参考方案1】:我假设所有用户的交互或自动事务仅在主数据库中完成(否则您将需要某种合并复制,这不是微不足道的)。
对于已删除的实体,有多种选择。在任何情况下,您的主数据库都必须将有关已删除实体的信息传播到客户端数据库。
1.如果信息被删除,每个实体都会持有该信息。
在这种情况下,您可以使用软删除选项,该选项可以通过覆盖 DbContext 的 OnModelCreating 和 SaveChanges 方法在 EF 中轻松实现(您可以在网上找到许多带有实现的代码示例)。 这个选项也有一些缺点——你可能有相当复杂的域模型与实体之间的关系,所以当你删除它们的父实体时,你必须注意软删除子实体。如果主数据库和客户端数据库有不同的前端应用程序,则必须升级所有这些应用程序以将新的软删除属性(例如 IsDeleted)付诸实施。但是在这种情况下,(软)删除的实体的同步本身非常简单,因为它只需要在客户端更新一个额外的属性。
2。已删除实体的新表。
在这种情况下,您必须在删除任何实体之前为每个实体创建一个附加表并插入 Id 值。您必须覆盖 DbContext 的 SaveChanges 以拦截处于 EntityState.Deleted 状态的实体。
关于第一个问题,这取决于您要增强什么。如果您希望表中有许多记录,您应该考虑引入额外的字段来仅更新那些在主数据库中真正更新的记录 - 您可以分别在 int(实体版本)、DateTime 或 guid 值之间进行选择,具体取决于什么最适合您的情况。
如果您想分离处理逐个属性更新的问题,您可以创建仅用于同步目的的特殊实体模型,将您的数据反序列化为这些对象,然后使用AutoMapper 更新您的实体,例如:
更新
dbUser = Mapper.Map<User>(apiUser);
db.Set<User>().Attach(dbUser);
db.Entry(dbUser).State = EntityState.Modified;
db.SaveChanges();
添加
dbUser = Mapper.Map<User>(apiUser);
db.client.Add(dbUser)
db.SaveChanges();
【讨论】:
以上是关于C# WPF Entity Framework 6 同步数据库的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 C# 的 Entity Framework 6 调用现有的存储过程
如何使用 Oracle 和 SQL Server 将 .NET 4.5 C# Entity Framework 6 中的列映射为大写?
使用 SQL Compact 4 和 Entity Framework 4 部署 WPF?
Entity Framework 6 中具有多个记录集的存储过程