Search code examples
mongodbmongodb-.net-driver10gen-csharp-driver

How can I update a inner property using the 10gen c# driver?


I have this structure:

public class User
{
    public ObjectId Id { get; set; }
    public Location Location { get; set; }
    public DateTime LastAround {get;set;}
}

public class Location
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

I've tried a few things but I want to update User's Location and when they were last around.

Tried this:

userHelper.Collection.Update(
    Query.EQ("_id", userId),
    Update.SetWrapped<Location>("Location", new Location { Latitude = latitude, Longitude = longitude }).Set("LastAround", DateTime.UtcNow));

and this:

userHelper.Collection.Update(
    Query.EQ("_id", userId),
    Update.Set("Location.Latitude", latitude)
        .Set("Location.Longitude", longitude)
        .Set("LastAround", DateTime.UtcNow));

Nothing worked...how can I do this?

Update 4/17:

userHelper.Collection.Update(
                Query.EQ("_id", new ObjectId(userId)),
                Update
                    .SetWrapped<Location>("Location", new Location { Longitude = longitude, Latitude = latitude })
                    .Set("LastAround", DateTime.UtcNow)
            );

The lng and lat value orders seem to be very important when doing queries on them. I was doing a geonear query and getting an strange out of bounds error. If you update in the wrong order it will put lats first and then you get the error.


Solution

  • Both of your original Update statements should work. I wrote a small sample program to demonstrate.

    After executing this Insert statement:

    var userId = ObjectId.GenerateNewId();
    var user = new User
    {
        Id = userId,
        Location = new Location { Latitude = 1.0, Longitude = 2.0 },
        LastAround = new DateTime(2012, 4, 14, 0, 0, 0, DateTimeKind.Utc)
    };
    collection.Insert(user);
    

    The document looks like this in the mongo shell:

    > db.test.find()
    { "_id" : ObjectId("4f8c5d33e447ad34b8c7ac84"), "Location" : { "Latitude" : 1, "Longitude" : 2 }, "LastAround" : ISODate("2012-04-14T00:00:00Z") }
    >
    

    After executing the first form of the Update statement:

    collection.Update(
        Query.EQ("_id", userId),
        Update
            .SetWrapped<Location>("Location", new Location { Latitude = 3.0, Longitude = 4.0 })
            .Set("LastAround", new DateTime(2012, 4, 15, 0, 0, 0, DateTimeKind.Utc)));
    

    the document looks like this:

    > db.test.find()
    { "_id" : ObjectId("4f8c5d33e447ad34b8c7ac84"), "Location" : { "Latitude" : 3, "Longitude" : 4 }, "LastAround" : ISODate("2012-04-15T00:00:00Z") }
    >
    

    And after executing the second form of the Update statement:

    collection.Update(
        Query.EQ("_id", userId),
        Update
            .Set("Location.Latitude", 5.0)
            .Set("Location.Longitude", 6.0)
            .Set("LastAround", new DateTime(2012, 4, 16, 0, 0, 0, DateTimeKind.Utc)));
    

    the document looks like this:

    > db.test.find()
    { "_id" : ObjectId("4f8c5d33e447ad34b8c7ac84"), "Location" : { "Latitude" : 5, "Longitude" : 6 }, "LastAround" : ISODate("2012-04-16T00:00:00Z") }
    >
    

    So the two forms of the Update statement are working.

    The full program is here:

    http://www.pastie.org/3799469