2012-04-15 59 views
2

我有这样的结构:如何使用10gen c#驱动程序更新内部属性?

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

液化天然气和纬度值的订单似乎对他们做查询时是非常重要的。我正在做一个geonear查询并得到一个奇怪的越界错误。如果您按照错误的顺序更新,它会先放入拉丁文,然后出现错误。

回答

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

文件看起来像这样在蒙戈外壳:

> 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

+0

奇怪,我不知道为什么我的工作不正常。我已经了解到,尽管geo查询lat和lng需要先切换lng。 – rball 2012-04-17 21:16:50

0

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

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

+0

是啊,一切都显得正常。无法让update语句正常工作。 – rball 2012-04-16 17:35:54

+0

我用一些示例代码开始了一个新的答案。 – 2012-04-16 18:01:14

+0

如果您的userId变量是字符串类型,并且您在调用Query.EQ时没有将其转换为ObjectId,则Find将找不到匹配的文档(因为字符串不能等于ObjectId)。因此,您的更新似乎可能没有执行更新,因为查询与任何文档都不匹配。 – 2012-04-16 18:04:47

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”,尽管可能没有最好的性能。 。:(

+0

此代码存在问题,因为FindAll从服务器返回所有文档,然后使用客户端在哪里找到要更新的文档。看到我从示例代码开始的新答案。 – 2012-04-16 18:03:02

+0

FindAll不是IQueryable?在其他情况下,我该如何正确地执行此命令?无论哪种情况,我会在今晚回家时尝试切换它。直到今天我还没有看到你的回复。 – rball 2012-04-17 21:19:44

+0

FindAll是IEnumerable,所以Where子句在客户端执行。您可以使用Query.EQ(“_ id”,id)创建查询并将其作为参数传递给Find。或者你可以调用collection.AsQueryable ().Where(u => u.Id = id)来使用LINQ to MongoDB。 – 2012-04-18 01:33:21

相关问题