如何使用10gen c#驱动程序更新内部属性?

时间:2012-04-15 01:06:06

标签: mongodb mongodb-.net-driver 10gen-csharp-driver

我有这个结构:

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; }
}

我尝试了一些事情,但我想更新用户的位置以及他们最后的时间。

试过这个:

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

和此:

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

什么都没有用......我怎么能这样做?

更新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)
            );

对它们进行查询时,lng和lat值命令似乎非常重要。我正在做一个geonear查询并得到一个奇怪的越界错误。如果您以错误的顺序更新它将首先放置拉特然后您得到错误。

3 个答案:

答案 0 :(得分:2)

两个原始的Update语句都应该有效。我写了一个小样本程序来演示。

执行此Insert语句后:

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);

文档在mongo shell中看起来像这样:

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

执行Update语句的第一种形式后:

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)));

该文件如下:

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

执行Update语句的第二种形式后:

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)));

该文件如下:

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

因此,Update语句的两种形式正在发挥作用。

完整的计划在这里:

http://www.pastie.org/3799469

答案 1 :(得分:0)

你的两种选择看起来都不错。

您确定您的userId变量具有正确的值吗?可能是Update没有找到要更新的匹配文档。

答案 2 :(得分:0)

我最终做了什么:

var userHelper = new MongoHelper<User>();
ObjectId id = new ObjectId(userId);
var user = userHelper.Collection.FindAll().Where(u => u.Id == id).Single();
user.LastAround = DateTime.UtcNow;
user.Location = new Location { Longitude = longitude, Latitude = latitude };
userHelper.Collection.Save(user);

哪个有效。不知道为什么其他方式不会。我认为这更像是“SQL”,尽管可能没有最佳性能。 :(