背景
ユーザー情報の時折最近の一部が正常にユーザー企業、ほとんどの開発者を復元する際に、システムの問題が発生し、復元されていない、バグは、コードの中で最も厄介ではありませんが、テストはバグを見つけましたが、私は再現に行った後、それが消えていました。私をからかってるの?
通信するための長い試みた後、最終的に手がかりを見つけたユーザーが複数の人の操作で同じ情報を変更する場合、この問題が発生します。
ああ、あなたは死んで、小さなバグです。
分析
ショートコードレビューの後、我々はユーザーを復元するときに、ユーザーコードが最初に出て、その後、ユーザー情報を変更して、データベースを変更するために、最後のユーザーを更新することがわかりました。
VAR USER1 = collection.Find(X => x.Id == " USER1 " ).FirstOrDefault(); user1.Name = " B " 。 collection.ReplaceOneAsync(X => x.Id == " USER1 "、USER1)。
これは、操作の前面の背面を覆うことができる、同時に実行コードを引き起こします。
図の以下の操作1と操作2実行した後に、A、18歳としてデータベース1内のユーザー名; 1つの操作がユーザ名Bが被覆されている修正することです。
したがって、我々は以下のコードを調整し、ユーザ情報アトミック操作を変更する必要が
UpdateDefinition <Persion>アップデート=ビルダー<Persion> .Update.Set(Y => y.Name、" B " )。 collection.UpdateOne(X => x.Id == " USER1 "、アップデート)。
データベースを置くために、このような変更操作は、プロパティを変更するために相互影響の操作を避けるためにのみ変更が行われます。
シンプルにそれを取るために神経を持っているように、神はここにいくつかの大きなTucao、何かが表示されます、以下に重点を置いて、辛抱強くお読みください。
重点
我々のデータ構造のこのような場合:
/// <要約> /// 人 /// </要約> [BsonIgnoreExtraElements] パブリック クラスPersion:BaseEntity { /// <要約> /// 名称 /// </要約> [BsonElement(" 名前" ) ] パブリック 文字列名前{ 取得します。セット; } /// <要約> /// 年龄 /// </要約> [BsonElement(" 年齢" )] パブリック int型の年齢{ GET; セット; } /// <要約> /// 亲戚 /// </要約> [BsonElement(" 親族" )] パブリックリスト<相対>親族{ 得ます。セット; } }
/// <要約> /// 亲属 /// </要約> パブリック クラス相対 { /// <要約> /// 名称 /// </要約> [BsonElement(" 名" )] パブリック 文字列名前{ 取得 ; セット; } /// <要約> /// 与本人关系 /// </要約> [BsonElement(" 関係" )] 公共の関係の関係{ 得ます。セットする; } }
/// <まとめ> /// Iとの関係 /// </要約> パブリック 列挙関係 { /// <まとめ> /// 父 /// </要約> 父= 0 、 /// <まとめ> /// 母 /// </要約> 母= 。1 、 /// <要約> /// 息子 /// </要約> 息子= 2 、 /// <要約> /// 娘 /// < /概要> 娘=3 、 /// <要約> /// 不明 /// </要約> unknow = 100 }
私たちが名更新したい場合は、「趙暁明を、」「趙ギャング、」「お父さん」として、親戚や自分自身との関係という男は、彼らが対処方法を検討してください。
注:人々はより多くの親戚を持つことができるので、一覧です。
その後、我々はUpdateOptionsに存在するArrayFiltersオブジェクトを使用し、MongoDBのインタフェースシステムを見ていない場合、私はほとんどの人がそれを無視すると信じています。
その使用それでまあ、ADO、見てみましょう
FilterDefinition <Persion>フィルタ=ビルダー<Persion> .Filter.Where(X => x.Name == " 赵小明" && x.Relatives =!ヌル && x.Relatives.Count> 0 ); UpdateDefinition <Persion>更新=ビルダー<Persion> .Update.Set(" 親戚$ [i]を.relationship。" 、Relationship.father)。 VaRのオプション= 新しいUpdateOptions() { ArrayFilters = 新しいリスト<ArrayFilterDefinition> { 新しい JsonArrayFilterDefinition <関係>(" { 'i.name': '赵刚' collection.UpdateMany(フィルタ、更新、オプション);
あなたが見ることができる、我々は、クエリへの氏、名「趙暁明、」人々は親戚に傾向があります。
そして、アップデート" 親類$ [I] .relationship。 "プロパティ、Relationship.father、として$は、[I]はプレースホルダです。
次いで、決定生成$を[I]値JsonArrayFilterDefinition <関係> (' {' i.name ':'ギャング「} " )。
最後に、これらの条件は、データベースを更新します。
拡張
まあ、更新が達成され、そして少しの好奇心のパートナーが存在することは、それを行う方法を探すことになるでしょうか?
これは単純ではない、1行の文では、取得します
VaRのユーザー= collection.Find(X => x.Name == " 赵小明" && x.Relatives!= nullの && x.Relatives.Count> 0 && x.Relatives.Exists(Y => y.Name == " 赵刚"。))FirstOrDefault();
この人は親戚の数千万人が存在する場合は、[はい、しかし、(実際の生活の中に、どのように、笑っ可能性が)、私はどのように行うためにメモリにロードされたオブジェクト全体を入れたくない、「趙ギャング」という名前の親戚との関係をされる必要があります?
その後、我々は、ProjectionDefinitionBuilderオブジェクトを使用する必要があり、
FilterDefinition <Persion>フィルタ=ビルダー<Persion> .Filter.Where(X => x.Name == " 赵小明" && x.Relatives =!ヌル && x.Relatives.Count> 0 ); VaRの findOptions = 新しい FindOptions <Persion、相対> () { 投影 = 新しい ProjectionDefinitionBuilder <Persion>()式(X => x.Relatives.FirstOrDefault(R => r.Name =!" 赵刚" )) }。 相対的カーソル = collection.FindSync(フィルタ、findOptions).FirstOrDefault();
私たちは、私たちが望む親戚を持って、代わりのフルPersionオブジェクトは、数十情報の親戚の何百万人ものが含まれています。
エピローグ
新しい芽ブログとして、私は私の問題を締結し、あなたとそれらを共有し、何かの間違った場所があり、正しいヘルプを確認してください。
もちろん、上記の通常の動作のためのギャングコンテンツである可能性が高いが、使用の少しはあなたにある場合には、同様に、コメントと懸念してください。
私はあなたに感謝し、戻って私は共有への皆のために仕事や勉強で遭遇興味深い質問になります!!!