我正在开发一个silverlight应用程序,我正在使用RIA数据服务和nHibernate。
目前,我有一个与另一个实体有一对多关系的实体。
public class Employer {
[Key]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class Person {
[Key]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
[Include]
[Association("PersonCurrentEmployer", "CurrentEmployerId", "Id", IsForeignKey = true)]
public virtual Employer CurrentEmployer { get; set; }
public virtual int? CurrentEmployerId { get; set; }
}
属性CurrentEmployerId
设置为不在映射中进行插入和更新。
在Silverlight方面,我将此人的CurrentEmployer
属性设置为客户端的现有雇主提交更改。
personEntity.CurrentEmployer = megaEmployer;
dataContext.SubmitChanges();
在服务器端,人员实体的CurrentEmployerId
设置为megaEmployer.Id
,但CurrentEmployer
为null
。因为我使用CurrentEmployer
属性而不是CurrentEmployerId
来保存关系,所以关系不会改变。
有没有办法强制RIA通过保存发送CurrentEmployer
对象,或者是否必须使用服务器端的CurrentEmployerId
来加载雇主并将其设置为{{1 }}?
答案 0 :(得分:1)
有没有办法强制RIA使用save发送CurrentEmployer对象,还是必须使用服务器端的CurrentEmployerId加载雇主并将其设置为CurrentEmployer?
我也遇到了这个问题。基本上,您要么必须使用[Composition]属性(我不推荐),要么从服务器端的数据库加载实体。组合混淆了客户端数据模型,并没有处理您需要担心的所有情况。 (在RIA forums.silverlight.net上有很多关于作文的内容)
[更新]一旦实现二级缓存,从数据库中读取支持实体的担心大多消失,因为它们将从缓存中加载。此外,如果您只需要NHibernate的代理不要抱怨,那么请查看Get / Load(永远不会记住哪个)..这将返回一个NH代理并将导致从数据库中选择单列和实体。 (如果你试图访问代理的另一个属性,NH将选择其余的属性。你可以在Ayende的博客上找到更多相关内容..)[/ UPDATE]
我遇到的最大问题是让NHib实际保存并加载关系。 (我也在使用Fluent)。到目前为止,责任方的反应是“哇哇,你不能这样做。看起来RIA并不是用NHib开发的”......这是一个垃圾回答,恕我直言。他们没有帮我弄清楚如何映射它,而是告诉我在我的实体中有一个ForeignKey我做错了(NHib不应该关心我的实体中有我的FK)......
答案 1 :(得分:1)
您在客户端没有看到CurrentEmployer的原因是您没有正确设置关联。
RIA服务不能以常规方式使用引用,因此在客户端引用您的雇主不起作用。 RIA服务与实体集一起使用,并根据关联属性创建“引用”。您的雇主需要一个与该人有关联的财产,如下所示。
public class Employer
{
private Person person;
[Key]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual int PersonID { get; set; }
[Include]
[Association("PersonCurrentEmployer", "PersonID", "Id", IsForeignKey = false)]
public virtual Person Person {
get
{
return this.person;
}
set
{
this.person = value;
if (value != null)
{
this.PersonID = value.Id;
}
}
}
}
答案 2 :(得分:0)
我想分享我为完成这项工作所做的工作,因为对这种情况的'官方'支持是......让我们说充其量只是无益,而且最糟糕的是粗暴无礼。
顺便说一下,你有同样的想法:使外键不插入/更新。但是,我也做了Generated.Always()。这样它总会读回值。
此外,我重写了DomainService.Submit()和DomainService.ExecuteChangeSet()。我在提交中启动了一个NHibernate事务(虽然我还不确定这是否符合我的预期)。
我没有将我的保存逻辑放在InsertSomeEntity()或UpdateSomeEntity()方法中,而是在ExecuteChangeSet中完成所有操作。这是因为NHibernate,它需要在NHibernate中执行动作之前使实体图完全双向并且水合。这包括当子项目来自RIA服务时从数据库或会话加载实体。 (我开始编写方法的路径,以获取图形的各种其他部分,因为那些专门的方法需要它们,但我发现在一个方法中更容易完成所有这些。而且,我遇到了RIA想要的问题我首先对子对象执行插入/更新,这对于新项目是个问题。)
我想对composition属性发表评论。我仍然支持我之前的评论,即不建议将其用于标准子实体集合,但是,它对于支持NHibernate组件非常有用,因为否则RIA将永远不会发回NHibernate工作所需的父组件(组合)。右。
我在这里没有提供任何代码,因为我必须做一些重编,但如果你想看到它,那对我来说不是问题。