RavenDB - 引用属性

3
在我目前正在开发的应用程序中,我刚刚使用RavenDB替换了db4o。我注意到有些东西不起作用,做了一些研究,现在需要一个检查。
假设这个领域模型:
人有姓名、地址和汽车属性。
汽车有制造商、型号和里程属性。
使用RavenDB,我可以创建并保存汽车。然后我可以创建一个人,并将汽车分配给该人的汽车属性。当我保存人时,汽车会保存在人中。一切看起来都很好。
问题是当我稍后更新Car.Mileage时。Car在RavenDB中得到更新,但在Person.Car中没有更新。Person.Car仍保留旧的里程数。
汽车存在于自己的范围内。Joe和Nancy都可以拥有这辆车,两个Person对象都将引用它。
在RavenDB中,应该如何处理这个问题?根据我所读关于聚合/根对象的所有内容,看起来我应该在Person中添加一个CarId属性。然后,当我加载Person时,也手动加载ID的Car。是这样吗?或者我可以将Car属性嵌入到Person中,并且以某种方式让所有Person对象显示正确的Person.Car.Mileage,因为Car.Mileage随时间变化而变化?

Bob,我会写一篇关于这个问题的文章,因为它似乎是一个常见的问题。 - Daniel Lang
谢谢,丹尼尔。您能否对整体方法发表评论?我需要在明天之前让它工作。我今天可以编写一种方式,然后再更改,但如果我第一次就能正确地完成它... - Bob Horn
请稍等几分钟... :) - Daniel Lang
请看我下面的答案,花费了几分钟的时间... - Daniel Lang
1个回答

2
如果我理解您的模型正确,那么您正在生成两份如下所示的文档:
{// cars/1
  "Make": "Honda",
  "Model": "Civic",
  "Mileage": 250000
}

就像这样:

{// persons/1
  "Name": "John Doe",
  "Address": "...",
  "Car": {
    "Id": "cars/1",
    "Make": "Honda",
    "Model": "Civic",
    "Mileage": 250000
  }
}

在这个文档模型中,重要的是所有汽车属性都已经在Person.Car属性中去规范化了。所以,在你的代码中,当你更新Car.Mileage并保存时,你最终得到的2个文档看起来像这样:

{// cars/1
  "Make": "Honda",
  "Model": "Civic",
  "Mileage": 999999
}

就像这样:

{// persons/1
  "Name": "John Doe",
  "Address": "...",
  "Car": {
    "Id": "cars/1",
    "Make": "Honda",
    "Model": "Civic",
    "Mileage": 250000
  }
}

这正是您告诉Raven要做的事情。使用此文档模型,为确保两个文档一致,您需要更新Car对象和所有使用该汽车的人的Person.Car.Mileage属性。

根据数据访问需求,您可以以几种不同的方式修改您的模型。其中一种选择是使您的模型看起来像这样:

{// cars/1
  "Make": "Honda",
  "Model": "Civic",
  "Mileage": 250000
}

就像这样:

{// persons/1
  "Name": "John Doe",
  "Address": "...",
  "Car": "cars/1"
}

使用这个文档模型,您只需要更新Car.Mileage属性。如果选择此选项,则还可以通过单个网络请求从Raven获取引用的文档。可以像这样执行:

var person = session.Include<Person>(x => x.Car).Load("persons/1");
var car = session.Load<Car>(person.Car);

但这只是更改文档模型以满足应用程序需求的一种选择。


谢谢回答。我认为你的第二种方法不受RavenDB社区的欢迎。虽然这仍然是我做事的方式。 :) - Bob Horn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接