草庐IT

c# - 在 mongodb 中执行高效的 upsert

coder 2023-11-05 原文

我有以下 C# 模型类:

public class Thingy
{        
    public ObjectId Id { get; set; }        
    public string Title { get; set; }
    public DateTime TimeCreated { get; set; }
    public string Content { get; set; }
    public string UUID { get; set; }
}

以及以下 ASP.MVC Controller 操作:

public ActionResult Create(Thingy thing)
{
    var query = Query.EQ("UUID", thing.UUID);
    var update = Update.Set("Title", thing.Title)
        .Set("Content", thing.Content);

    var t = _collection.Update(query, update, SafeMode.True);
    if (t.UpdatedExisting == false)
    {
        thing.TimeCreated = DateTime.Now;
        thing.UUID = System.Guid.NewGuid().ToString();
        _collection.Insert(thing);
    }

        /*
        var t = _collection.FindOne(query);

        if (t == null)
        {
            thing.TimeCreated = DateTime.Now;
            thing.UUID = System.Guid.NewGuid().ToString();
            _collection.Insert(thing);                
        }
        else
        {
            _collection.Update(query, update);                
        }
        */
        return RedirectToAction("Index", "Home");
    }

此方法执行更新或插入。如果需要插入,则必须设置 UUID 和 TimeCreated 成员。如果需要进行更新,则必须单独保留 UUID 和 TimeCreated,但必须更新成员 Title 和 Content。

注释掉的代码有效,但似乎不是最有效的。当它调用 FindOne 时,这是到 mongodb 的一次旅行。然后,如果转到 else 子句,它会执行另一个查询和更新操作,因此还有 2 次访问 mongodb。

什么是完成我想要完成的事情的更有效方法?

最佳答案

如链接的 SO 答案中所述,要使更新插入起作用,您需要更新整个文档,而不仅仅是几个属性。

我个人会将 CreateEdit 分开到单独的 MVC 操作中。建议零售价。创建 Thingy 与更新它有不同的注意事项。

如果您仍想执行更新插入而不是单独的插入/更新调用,则需要使用以下代码:

_collection.Update(
    Query.EQ("UUID", thing.UUID),
    Update.Replace(thing),
    UpsertFlags.Upsert
);

现在的问题是,我们如何确保 thing 对两种情况(即插入和更新)都具有适当的值。

我的假设是(基于您的代码模型绑定(bind)到 Thingy 实例),您的 View 正在发回所有字段(包括 UUIDTimeCreated)。这意味着,在更新的情况下, View 已经为 UUIDTimeCreated 预填充了值。因此,在更新 Thingy 的情况下,thing 对象具有最新值。

现在,在创建的情况下,当呈现 View 时,您可以为 TimeCreated 字段存储 DateTime.MinValue。在您的 Create MVC 操作中,您可以检查 TimeCreated 是否为 DateTime.MinValue,然后将其设置为当前时间并存储一个新值UUID

这样,在插入的情况下,thing 也具有最新值。因此,我们可以安全地进行更新插入。

关于c# - 在 mongodb 中执行高效的 upsert,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12460005/

有关c# - 在 mongodb 中执行高效的 upsert的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  3. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  5. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  6. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  9. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  10. python - 是否可以使用 Ruby 或 Python 禁用 anchor /引用来发出有效的 YAML? - 2

    是否可以在PyYAML或Ruby的Psych引擎中禁用创建anchor和引用(并有效地显式列出冗余数据)?也许我在网上搜索时遗漏了一些东西,但在Psych中似乎没有太多可用的选项,而且我也无法确定PyYAML是否允许这样做.基本原理是我必须序列化一些数据并将其以可读的形式传递给一个不是真正的技术同事进行手动验证。有些数据是多余的,但我需要以最明确的方式列出它们以提高可读性(anchor和引用是提高效率的好概念,但不是人类可读性)。Ruby和Python是我选择的工具,但如果有其他一些相当简单的方法来“展开”YAML文档,它可能就可以了。 最佳答案

随机推荐