当前位置: 首页 > 知识库问答 >
问题:

C#WPF实体框架6同步数据库

阙庆
2023-03-14

场景:

我有两个MySQL数据库:

  1. 大型主数据库
  2. 小型客户端数据库

示例表:

大数据库用户:

文本用户名

  • int id
  • varchar登录
  • varchar密码
  • ...更多的领域

客户端数据库用户

  • 内部id
  • int UNIQUE api\u id(来自master的id)
  • varchar登录
  • varchar密码

问题:我需要同步数据库,但我不知道如何以最佳方式进行同步。我读过这个问题,但它很老了,没有涵盖我的情况。我通过REST API与主数据库通信,直接连接不是选项。

我的同步算法

  • 从REST API(例如/API/users/)下载数据并将其反序列化到ApiUser对象列表

    public class ApiUser {
      int id;
      string login;
      string password; 
    }

    public class User{
      int id;
      int api_id;
      string login;
      string password; 
    }

  • 迭代Apiuser列表
    • 如果存在带有ApiUser.id实体,则覆盖所有字段
    • 否则创建新实体

    我的代码:

    public void syncUsers(List <ApiUser> ApiUsers)
    
        {
            using (var db = new dbEntities())
            {
                ApiUsers.ForEach(apiUser =>
                {
                    var dbUser = db.client
                        .Where(c => c.api_id == apiUser.id)
                        .SingleOrDefault();
    
                    if (dbUser == null)
                    {
                        var userObj = new user()
                        {
                            api_id = apiUser.id,
                            login = apiUser.login,
                            password = apiUser.password
                        };
                        db.client.Add(userObj);
                    }
                    else
                    {
                        dbUser.api_id = apiUser.id,
                        dbUser.login = apiUser.login,
                        dbUser.password = apiUser.password
                    }
    
                });
    
                db.SaveChanges();
            }
        }
    
    

    问题:如何做得更好?我在主数据库中删除实体时遇到问题,我的算法不涵盖这种情况。

共有1个答案

屠君墨
2023-03-14

我假设所有用户的交互或自动事务都只在master数据库中完成(否则您将需要某种合并复制,这不是微不足道的)。

对于已删除的实体,有几个选项。在任何情况下,主数据库都必须将有关已删除实体的信息传播到客户端数据库。

1.如果信息被删除,每个实体都保留该信息。

在这种情况下,您可以使用软删除选项,该选项可以通过覆盖DbContext的OnModelCreating和SaveChange方法在EF中轻松实现(您可以在网上找到许多带有实现的代码示例)。此选项也有一些缺点——您可能有相当复杂的域模型以及实体之间的关系,因此在删除其父实体时必须处理软删除子实体。如果您有不同的主数据库和客户端数据库的前端应用程序,您必须升级所有这些应用程序才能将新的软删除属性(例如IsDelated)投入使用。但是在这种情况下,(软)删除实体的同步本身非常简单,因为它只需要在客户端更新一个附加属性。

2、删除实体的新表。

在这种情况下,您必须为每个实体创建一个附加表,并在删除任何实体之前插入Id值。您必须重写DbContext的SaveChanges以拦截EntityState中的实体。已删除状态。

关于第一个问题,这取决于您想要增强什么。如果希望表中有许多记录,则应考虑引入其他字段,仅更新在主数据库中真正更新过的记录-您可以分别在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();
 类似资料:
  • 这是我的代码: 但是当我从控制器调用函数时。它显示错误 在上一个异步操作完成之前,在此上下文上启动了第二个操作。使用“await”确保在该上下文上调用另一个方法之前已完成任何异步操作。任何实例成员都不能保证线程安全。 请帮我解决这个问题。

  • 问题内容: 我希望将动态连接字符串传递给实体框架上下文。我有150多个相同的模式(每个帐户一个),我想这样选择连接: 从理论上讲,这很容易,因为我可以创建一个connectionString并将其作为构造函数的参数传递,例如: 仅传递连接字符串名称时,我可以成功连接,但如下所示动态生成时,则不能成功。我现在意识到这是因为web.config中的连接字符串具有属性。 但是,当我将实际的连接字符串动态

  • 我曾想过简单地对数据库运行一个小命令并捕获任何异常,然而,如果出现问题(例如app.config丢失或数据库服务器关闭),应用程序将花费大量时间运行此代码,然后抛出异常(大约1分钟)。我想这是由于连接超时等,但我已经摆弄了这样的属性没有任何作用。 有没有人能提供任何关于去哪里的建议?

  • 问题内容: 我在项目中使用EDM模型。 当我通过发布请求在数据库中插入俄语单词时,我得到 控制器: 在数据库中,所有字符集都设置为utf-8 在布局页面中,内容的enc类型为utf-8 数据库代码: 问题答案: 添加到Entity Framework的连接字符串中 这是一个工作添加节点:

  • 我有一个带有“Status”布尔值的付款模型,该布尔值默认为false。付款后,我需要将特定付款的“状态”更新为true。 这是我一直试图用来更改特定数据库条目的代码,但它并没有改变它。我做错了什么? 谢谢 这就是最终起作用的原因:

  • 防止在ASP.NET MVC中对使用属性的特定操作进行缓存 ASP.NET MVC如何禁用自动缓存选项?