2011-11-11 34 views
2

次のクラスがあるとします。それは私が新しいエージェントを取得するときに、エージェントがC#を使用してmongodbの埋め込みドキュメントを更新します

public class AgentHistory 
{ 
    public ObjectId Id { get; set; } 
    public Guid SystemId { get; set; } 
    public Guid CampaignId { get; set; } 
    public List<Agent> 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); 
    } 

次の例外が発生します.NET型Riverdale.Domain.BO.AgentはBsonValueにマップできません。私は間違って何をしていますか?埋め込みコレクションを更新する正しい方法は何ですか? BsonValue.Create()BsonArray.Createが要求されるべきではない:あなたはとても冗長である必要はありません

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<string> 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<string> 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<A>("AgentHistory"); 
     } 


     private MongoCollection<A> _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); 
     } 
    } 
+0

はあなたがAgentクラスを表示することができますか? –

+0

public class Agent { public string LocalIdentifier {get;セット; } public string AgentName {get;セット; } } –

答えて

1

は、ここで(単なるデモのように)投げるシンプルなコンソールアプリケーションです。

実際には、後者が問題の原因です。BsonArray.Createの配列が作成されます。しかし、オブジェクトの配列が必要です。 BsonArray.Createの利用可能なオーバーロードを見れば、あなたはBsonArray.Create(IEnumerable)を呼び出すでしょう、それは望ましくありません。

あなたは単に代わり

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

を使用しようとしたことがありますか? JSONでは

は、差は次のようになります値の

配列:[ヴァル、ヴァル、...]オブジェクトの

配列:[{...}、{たとえば...}、...]

単純配列:オブジェクトの

アレイ:[ { userId: 2314234, comment: "Foo" }, { ... }, ... ]

+0

それでも、あなたが追加した構文はまさに私が欲しかったものです。ありがとうございました –

+0

'_mongoCollection.Update(BuildIdentityQuery(entity)、Update.AddToSetEachWrapped(" Agents "、entity.Agents) 、SafeMode.True); 'Update.Set'(やはり)はリストやドキュメントを受け付けないので、動作します。ただし、リストをリセットすることはできません。追加することができるのは**または**のみです。代わりに、単にオブジェクト全体を更新するか、独自のオブジェクトでリストをラップし、 'Update.SetWrapped'を使用します。 – mnemosyn

+0

クール、それは動作します。 Update.Setがリストや文書を受け入れないのはなぜですか? –

関連する問題