使用C#更新mongodb中的嵌入式文档

假设你有下一堂课。 它包含代理已运行的系统

public class AgentHistory { public ObjectId Id { get; set; } public Guid SystemId { get; set; } public Guid CampaignId { get; set; } public List Agents { get; set; } } 

现在,当我得到一个新的代理时,我会做下一件事:

  public override AgentHistory Save(AgentHistory agent) { if (agent == null) throw new ArgumentNullException("agent"); if (_repository.Exists(agent)) { AgentHistory dbEntity = _repository.FindById(agent.SystemId, agent.CampaignId); dbEntity.Agents.AddRange(agent.Agents); _repository.UpdateAgentHistory(dbEntity); } else { _repository.Save(agent); } return agent; } 

以及存储库中的下一个方法:

 public void UpdateAgentHistory(AgentHistory updatedEntity) { QueryComplete query = Query.EQ("_id", BsonValue.Create(updatedEntity.Id)); MongoCollection.Update(query, Update.Set("Agents", BsonArray.Create(updatedEntity.Agents)), UpdateFlags.None, SafeMode.True ); } 

我得到下一个exception.NET类型Riverdale.Domain.BO.Agent无法映射到BsonValue。 我究竟做错了什么? 更新嵌入式集合的正确方法是什么?

这是一个更简单的控制台应用程序抛出(就像一个演示):

  public class Agent { [BsonId] public string LocalIdentifier { get; set; } public string AgentName { get; set; } } public class A { public ObjectId Id { get; set; } public Guid SystemId { get; set; } public Guid CampaignId { get; set; } public Agent[] Agents { get; set; } } public class AgentHistoryRepository { public bool Exists(A agentHistory) { return _mongoCollection.FindOne(BuildIdentityQuery(agentHistory)) != null; } public void Delete(A agentHistory) { _mongoCollection.Remove(BuildIdentityQuery(agentHistory)); } public List GetAgentsForASystem(Guid systemGuid) { QueryComplete query = Query.EQ("SystemId", systemGuid); return _mongoCollection.Find(query).SelectMany(x => x.Agents.Select(z => z.AgentName)).Distinct().ToList(); } public List GetAgentsForACampaign(Guid systemGuid, Guid campaignGuid) { QueryComplete query = Query.EQ("CampaignId", campaignGuid); if (systemGuid != Guid.Empty) query = Query.And(new[] {query, Query.EQ("SystemId", systemGuid)}); return _mongoCollection.Find(query).SelectMany(x => x.Agents.Select(z => z.AgentName)).Distinct().ToList(); } public AgentHistoryRepository() { string connectionString = "mongodb://localhost/Sample"; var mgsb = new MongoUrlBuilder(connectionString); var MongoServer = MongoDB.Driver.MongoServer.Create(mgsb.ToMongoUrl()); var MongoDatabase = MongoServer.GetDatabase(mgsb.DatabaseName); _mongoCollection = MongoDatabase.GetCollection("AgentHistory"); } private MongoCollection _mongoCollection; private QueryComplete BuildIdentityQuery(A agentHistory) { QueryComplete query = Query.And(Query.EQ("SystemId", agentHistory.SystemId), Query.EQ("CampaignId", agentHistory.CampaignId)); return query; } public void Save(A entity) { _mongoCollection.Insert(entity, SafeMode.True); } public void UpdateAgents(A entity) { _mongoCollection.Update(BuildIdentityQuery(entity), Update.Set("Agents", entity.Agents.ToBsonDocument())); } } internal class Program { public static void Main() { var objectToSave = new A {Id = ObjectId.GenerateNewId(), CampaignId=Guid.NewGuid(), SystemId =Guid.NewGuid() , Agents = new [] {new Agent{LocalIdentifier="agent", AgentName= "name"}}}; var repo = new AgentHistoryRepository(); repo.UpdateAgents(objectToSave); objectToSave.Agents = new[] { new Agent { LocalIdentifier = "agent2", AgentName = "name2" } }; repo.UpdateAgents(objectToSave); var objectToSave2 = new A { Id = ObjectId.GenerateNewId(), CampaignId = Guid.NewGuid(), SystemId = objectToSave.SystemId, Agents = new [] { new Agent { LocalIdentifier = "agent", AgentName = "name" } } }; repo.UpdateAgents(objectToSave2); foreach (var agentName in repo.GetAgentsForASystem(objectToSave.SystemId)) Console.WriteLine(agentName); } } 

你不必如此冗长:不应该要求BsonValue.Create()BsonArray.Create

实际上,后者是导致问题的原因: BsonArray.Create创建值类型的数组 。 但是,您需要一组对象。 如果你看一下BsonArray.Create的可用重载,我想你会调用BsonArray.Create(IEnumerable) ,这是不可取的。

你试过简单地使用吗?

 MongoCollection.Update(query, Update.Set("Agents", updatedEntity.Agents), ...); 

代替?

在JSON中,差异如下所示:

值数组:[val,val,…]

对象数组:[{…},{…},…]

例如,

简单数组: [ "mongodb", "awesomness", ... ]

对象数组: [ { userId: 2314234, comment: "Foo" }, { ... }, ... ]