I am trying to update individual fields in a deeply nested array.
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; }
}
Updating a field in a level-1 array works like a charm. Updating a field in a level-2 array fails.
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"));
}
I understand that multiple positional operators are not supported, so my last line (m.Vehicles[-1].Parts[-1].Name) is kind of crap.
Obviously I am not the only one having this problem and I found different solutions like this or that. However, none of them is type safe. The resulting code is pretty ugly and error prone.
So I was wondering: Is there any way to redesign my code so it is type safe?
I am using MongoDb 4.0.9 and C# driver 2.11.5.
Edit (01-11-2020): For anybody interested, I found this really nice extension by Massimiliano Kraus, which is a bit outdated (2017), but is still working and turned out to be a huge help. Thank you, Massimiliano! MongoDB.DeepUpdater.CSharp