[英]How to update a field “type-safe” in a deeply nested array with C# MongoDb driver?
我正在嘗試更新深度嵌套數組中的各個字段。
public class Maker
{
public int Id { get; set; }
public List<Vehicle> Vehicles { get; set; }
}
public class Vehicle
{
public int Id { get; set; }
public int Price { get; set; }
public List<Part> Parts { get; set; }
}
public class Part
{
public int Id { get; set; }
public string Name { get; set; }
}
更新 1 級數組中的字段就像一個魅力。 更新 2 級數組中的字段失敗。
public void UpdateNestedArrayFields()
{
var client = new MongoClient();
var db = client.GetDatabase("test");
var makers = db.GetCollection<Maker>("makers");
// Create a maker and add a vehicle
var newPart = new Part() { Id = 34, Name = "Wheel" };
var newVehicle = new Vehicle() { Id = 17, Price = 1000, Parts = new List<Part>() { newPart } };
var newMaker = new Maker() { Id = 5, Vehicles = new List<Vehicle>() { newVehicle } };
// Update vehicle's price (WORKS)
makers.FindOneAndUpdate(
m => m.Id == newMaker.Id && m.Vehicles.Any(v => v.Id == newVehicle.Id),
Builders<Maker>.Update.Set(m => m.Vehicles[-1].Price, 2000));
// Update part's name (**FAILS**)
makers.FindOneAndUpdate(
m => m.Id == newMaker.Id && m.Vehicles.Single(v => v.Id == newVehicle.Id).Parts.Any(p=> p.Id == newPart.Id),
Builders<Maker>.Update.Set(m => m.Vehicles[-1].Parts[-1].Name, "Tire"));
}
我知道不支持多個位置運算符,所以我的最后一行 (m.Vehicles[-1].Parts[-1].Name) 有點廢話。
顯然我不是唯一一個遇到這個問題的人,我找到了類似這樣或那樣的不同解決方案。 但是,它們都不是類型安全的。 生成的代碼非常丑陋且容易出錯。
所以我想知道:有沒有辦法重新設計我的代碼,使其類型安全?
我正在使用 MongoDb 4.0.9 和 C# 驅動程序 2.11.5。
編輯(01-11-2020):對於任何感興趣的人,我發現 Massimiliano Kraus 的這個非常好的擴展,它有點過時(2017 年),但仍在工作,結果證明是一個巨大的幫助。 謝謝你,馬西米利亞諾! MongoDB.DeepUpdater.CSharp
還有一個類型化嵌套數組更新的其他可能且類型更多的版本。 它沒有完全輸入,但它更接近你的需要。
它也使用ArrayFilters
但以更多類型的方式
此代碼直接來自我正在處理的應用程序。
var filter = Builders<EventModel>.Filter.Eq(s => s.Id, eventId);
var settingsPath = @$"{nameof(EventModel.EventLayout)}.{nameof(EventLayoutSetting.Pages)}.$[page].{nameof(Page.Components)}.$[component].{nameof(Component.Settings)}";
var update = Builders<EventModel>.Update.
Set(settingsPath, settings);
var dbResult = await eventsCollection.UpdateOneAsync(filter, update, new UpdateOptions
{
ArrayFilters = new List<ArrayFilterDefinition>
{
new BsonDocumentArrayFilterDefinition<BsonDocument> (new BsonDocument($"page.{nameof(Page.PageId)}",pageId)),
new BsonDocumentArrayFilterDefinition<BsonDocument> (new BsonDocument($"component.{nameof(Component.ComponentId)}",componentId))
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.