具有相等成员的对象的RavenDb奇怪行为
当我试图将对象列表存储到ravendb时,我发现了代码中的一个奇怪错误。问题是要存储的对象具有由resharper生成的相等成员。问题的目的如下:请注意,我已经对平等成员提出了意见,以解决该问题-具有相等成员的对象的RavenDb奇怪行为,ravendb,Ravendb,当我试图将对象列表存储到ravendb时,我发现了代码中的一个奇怪错误。问题是要存储的对象具有由resharper生成的相等成员。问题的目的如下:请注意,我已经对平等成员提出了意见,以解决该问题- //[DataContract(Namespace = "")] //[KnownType(typeof(IApplicationEntity))] public class ApplicationEntity: IApplicationEntity { public Application
//[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);
//}
}
奇怪的行为是,由于列表有400个成员,我希望Key字段增加到400,但是存储的前10个对象的Key是正确的,即0到9。但是第11个又从0开始,以此类推
但是如果我在上面的代码片段中注释了equality members offas,那么这个问题就消失了
另外,如果我一次添加一个对象,而不是批处理,问题就会消失-
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++;
}
}
我知道我已经解决了这个问题,但我不明白这里发生了什么,为什么只有关键领域受到影响?这是一个未定义的行为,我很担心,因为代码应该部署在生产中!!很明显,平等成员没有定义。我需要追根究底,这是一个bug吗?不,我认为RavenDB中没有这样的bug。相反,我想您的代码还有另一个问题,因为基于上述示例的测试对我来说很有效:
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));
}
}
}
}
}
如果您希望我们对此进行进一步调查,请提供一个失败的测试。您的代码和我的代码之间存在一些差异-我没有使用嵌入式版本。我已经安装了raven作为一项服务。如果我按照您的方式安装,就不会有问题,这个问题很难重现。在我的代码中似乎没有任何问题,好像我注释掉了平等成员,问题就消失了。从我的代码中可以明显看出,没有抽象,我直接使用文档存储。如果您使用的是EmbeddedBledDocumentStore或已安装的服务,则没有区别。这是一个xUnit测试,这是复制事物的一种方法。如果我不能复制这种行为,我就不能告诉你它是不是一个bug,你能做些什么。
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));
}
}
}
}
}