在RavenDb中存储我的对象时出现以下错误
我只为存储对象分配一个键,我使用重载的存储方法来存储实体。
存储只被称为一次所以为什么会抛出这样的异常。我不明白对象身份有什么。
Id
属性除了ravendb持久性之外还有其他目的。
Entity UserQuery+MyItem had document key 'mykeypath/44' but now has document key property 'MyItems/44'. You cannot change the document key property of a entity loaded into the session
。
void Main()
{
var host = "http://myhost:8020";
var _documentStore = new DocumentStore { Url = host, DefaultDatabase = "sdb" };
_documentStore.Initialize();
using (var session = _documentStore.OpenSession())
{
var path = "mykeypath/44";
session.Store(new MyItem { Id = 303, Test = "TEST" }, path);
session.SaveChanges();
}
}
public class MyItem : AuditableEntity {
public string Test { get; set; }
}
[Serializable]
public abstract class AuditableEntity : IAuditable
{
[DataMember]
[Display(Name = "Id", Description = "Id")]
public long Id { get; set; }
[DataMember]
[Display(Name = "Modified By", Description = "Modified By")]
public string ModifiedBy { get; set; }
[DataMember]
[Display(Name = "Modified Date", Description = "Modified Date")]
public DateTime ModifiedDate { get; set; }
}
答案 0 :(得分:3)
如果您的类有一个名为Id
的属性,RavenDB默认会将其用作文档ID。
在您的情况下,如果MyItem
的实例Id
设置为303
,则意味着该文档将保存在ID为MyItems/303
的数据库中。
您可以通过修改
轻松测试session.Store(new MyItem { Id = 303, Test = "TEST" }, path);
与
对齐session.Store(new MyItem { Id = 303, Test = "TEST" });
这将有效,结果将是:
因此,问题在于您指示Raven为您的对象分配两个ID:
MyItems/303
,由于Id
属性mykeypath/44
,因为您使用Store
重载明确设置此ID。我在这种情况下应用的解决方案是重命名Id
属性。如果那是不可能的(例如:该类已经用于其他目的,如WCF合同),请考虑创建一个仅用于RavenDB持久性的新类,并在两者之间进行映射(像AutoMapper这样的工具使这很简单)。
我找到了一种通过查看this thread来弯曲Id
字段约定的方法。
在您的情况下,您应该在开始会话之前执行以下操作:
_documentStore.Conventions.FindIdentityProperty =
prop =>
{
if (prop.DeclaringType == typeof (AuditableEntity))
return prop.Name == "CustomId";
return prop.Name == "Id";
};
这说明类型Id
定义的属性AuditableEntity
不应用作文档标识符。在所有其他情况下,请执行默认操作。
我测试了它并且工作正常,在RavenDb工作室中显示了两个Id字段:):