2012-01-29 64 views
0

當我嘗試將對象列表存儲到ravendb時,我遇到了一個奇怪的錯誤(在我的代碼中)的底部。問題在於要存儲的對象具有由resharper生成的相等成員。有問題的目標如下所示(請注意我註釋掉的平等成員,以解決這一問題) -RavenDb使用等於成員的對象的奇怪行爲

//[DataContract(Namespace = "")] 
//[KnownType(typeof(IApplicationEntity))] 
public class ApplicationEntity: IApplicationEntity 
{ 

    public ApplicationEntity() 
    { 

    } 
    public ApplicationEntity(string processName) 
    { 
     ProcessName = processName; 
     Id = "Processes/" + ProcessName; 
    } 

    public ApplicationEntity(string key, string processName) 
    { 
     ProcessName = processName; 
     Key = key; 
     Id = string.Format("Processes/{0}_{1}", Key, ProcessName); 

    } 


    //[DataMember] 
    public string Id { get; set; } 
    //[DataMember] 
    public string Key { get; set; } 
    //[DataMember] 
    public string ProcessName { get; set; } 
    //[DataMember] 
    public string ProcessDescription { get; set; } 
    /// <summary> 
    /// used to generate sequential unique activity ID generation only. 
    /// </summary> 
    //[DataMember] 
    public string ActivityCount { get; set; } 

    //public bool Equals(ApplicationEntity other) 
    //{ 
    // if (ReferenceEquals(null, other)) return false; 
    // if (ReferenceEquals(this, other)) return true; 
    // return Equals(other.ProcessName, ProcessName); 
    //} 

    //public override bool Equals(object obj) 
    //{ 
    // if (ReferenceEquals(null, obj)) return false; 
    // if (ReferenceEquals(this, obj)) return true; 
    // if (obj.GetType() != typeof (ApplicationEntity)) return false; 
    // return Equals((ApplicationEntity) obj); 
    //} 

    //public override int GetHashCode() 
    //{ 
    // return (ProcessName != null ? ProcessName.GetHashCode() : 0); 
    //} 
} 

現在,如果我存儲平等成員對象實現然後將下面的代碼會產生奇怪的結果 -

int count = 0; 
     using (var session = _store.OpenSession(_databaseName)) 
     { 


      foreach (var applicationEntity in _listOfApplications) 
      { 
       var entity = new ApplicationEntity(count.ToString(), applicationEntity.ProcessName); 


       //ravenRepositoryCachable.Add(entity); 
       session.Store(entity); 


       count++; 


      } 

      session.SaveChanges(); 
     } 

奇怪的行爲是,我期望密鑰字段增加到400,因爲列表有400個成員,但是存儲的前10個對象的密鑰是正確的,即0到9,但第11個開始從0再次等等。

但是,如果我評論相等成員關閉(如上面的代碼片段),那麼這個問題就會消失。

另外,如果我增加在時間的對象一個,而不是批量問題消失 -

int count = 0; 
     foreach (var applicationEntity in _listOfApplications) 
     { 
      using (var session = _store.OpenSession(_databaseName)) 
      { 
       var entity = new ApplicationEntity(count.ToString(), applicationEntity.ProcessName); 


       //ravenRepositoryCachable.Add(entity); 
       session.Store(entity); 
       session.SaveChanges(); 

       count++; 

      } 
     } 

我知道我已經解決了這個問題,但我不明白這裏發生了什麼,爲什麼只有關鍵領域受到了影響?這是一個未定義的行爲,我很擔心,因爲代碼應該在生產中部署!很明顯,平等成員是不會被界定的。我需要了解它的底部,這是一個錯誤?

回答

0

不,我不認爲RavenDB存在這樣的錯誤。相反,我想有你的代碼的另一個問題,因爲這個測試(即基於你上面的例子),工作對我來說:

public class EqualityMembersInSessionCache 
{ 
    public class ApplicationEntity 
    { 
     public ApplicationEntity(string key, string processName) 
     { 
      ProcessName = processName; 
      Key = key; 
      Id = string.Format("Processes/{0}_{1}", Key, ProcessName); 
     } 


     public string Id { get; set; } 
     public string Key { get; set; } 
     public string ProcessName { get; set; } 


     public bool Equals(ApplicationEntity other) 
     { 
      if (ReferenceEquals(null, other)) return false; 
      if (ReferenceEquals(this, other)) return true; 
      return Equals(other.ProcessName, ProcessName); 
     } 

     public override bool Equals(object obj) 
     { 
      if (ReferenceEquals(null, obj)) return false; 
      if (ReferenceEquals(this, obj)) return true; 
      if (obj.GetType() != typeof(ApplicationEntity)) return false; 
      return Equals((ApplicationEntity)obj); 
     } 

     public override int GetHashCode() 
     { 
      return (ProcessName != null ? ProcessName.GetHashCode() : 0); 
     } 
    } 

    [Fact] 
    public void Has_correct_behaviour() 
    { 
     var randomNames = new List<string>(); 
     for (int c = 1; c < 100; c++) 
     { 
      randomNames.Add(string.Format("test{0}", c)); 
     } 

     using (var store = new EmbeddableDocumentStore { RunInMemory = true }) 
     { 
      int count = 0; 
      using (var session = store.OpenSession()) 
      { 
       foreach (var name in randomNames) 
       { 
        session.Store(new ApplicationEntity(count.ToString(), name)); 
        count++; 
       } 
       session.SaveChanges(); 
      } 

      using (var session = store.OpenSession()) 
      { 
       var results = session.Query<ApplicationEntity>() 
        .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite()) 
        .ToList(); 

       Assert.NotEmpty(results); 
       Assert.Equal(99, results.Count); 
       for (int c = 0; c < 99; c++) 
       { 
        Assert.Equal(c, int.Parse(results[c].Key)); 
       } 
      } 
     } 
    } 
} 

如果您希望我們在這進一步調查,請提供一個失敗的測試。

+0

你和我的代碼之間的一些區別 - 我沒有使用嵌入式版本。我已將烏鴉作爲服務安裝。 – NiladriBose 2012-01-30 14:38:06

+0

如果我這樣做沒有問題,這個問題很難重現。在我的代碼中似乎沒有任何問題,就好像我註釋掉問題消失時的平等成員。從我的代碼中可以看出,沒有抽象,我直接使用文檔存儲。 – NiladriBose 2012-01-30 14:40:26

+0

如果您使用EmbeddableDocumentStore或已安裝的服務,則沒有區別。這是一個xUnit-Test,這是重現事物的一種方法。如果我無法再現這種行爲,我無法告訴您它是否是一個錯誤(或不是),以及您可以做些什麼。 – 2012-01-30 15:36:12