【问题标题】:Trouble updating one to many relationships when using ria services with nhibernate将 ria 服务与 nhibernate 一起使用时无法更新一对多关系
【发布时间】:2010-10-05 00:16:10
【问题描述】:

我正在开发一个 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,但CurrentEmployernull。因为我使用CurrentEmployer 属性而不是CurrentEmployerId 来保存关系,所以关系没有改变。

有没有办法强制 RIA 发送带有保存的 CurrentEmployer 对象,还是我必须在服务器端使用 CurrentEmployerId 来加载雇主并将其设置为 CurrentEmployer

【问题讨论】:

标签: silverlight nhibernate ria


【解决方案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】:

    有没有办法强制 RIA 发送带有保存的 CurrentEmployer 对象,还是我必须使用服务器端的 CurrentEmployerId 来加载雇主并将其设置为 CurrentEmployer?

    我也遇到了这个问题。基本上,您要么必须使用 [Composition] 属性(我不推荐),要么从服务器端的数据库中加载实体。组合混淆了客户端数据模型,并且无法处理您需要担心的所有情况。 (RIA forums.silverlight.net 上有更多关于 Composition 的内容)

    [更新] 一旦你实现了二级缓存,从数据库中读取支持实体的担心就基本消失了,因为它们将从缓存中加载。此外,如果您只需要 NHibernate 的代理而不抱怨,那么请查看 Get/Load(永远不记得哪个).. 这将返回一个 NH 代理并导致从数据库中选择单列和实体. (如果您尝试访问代理的其他属性,NH 将选择其余属性。您可以在 Ayende 的博客上找到更多信息。)[/UPDATE]

    我遇到的最大问题是让 NHib 实际保存和加载关系。 (我也在使用 Fluent)。到目前为止,责任方的回应是“哇,你不能那样做。看起来 RIA 的开发没有考虑到 NHB” .. 这是一个废话答案,恕我直言。他们没有帮我弄清楚如何映射它,而是告诉我我做错了,因为我的实体中有一个 ForeignKey(NHib 不应该关心我的实体中有我的 FK)......

    【讨论】:

      【解决方案3】:

      我想分享我为完成这项工作所做的工作,因为对这种情况的“官方”支持是......让我们说最好的情况是没有帮助,最坏的情况是完全粗鲁。

      顺便说一句,您的想法与我相同:使外键不插入/更新。但是,我也将其设为 Generated.Always()。这样它总是会读回该值。

      另外,我覆盖了 DomainService.Submit() 和 DomainService.ExecuteChangeSet()。我在提交中启动了 NHibernate 事务(尽管我还不确定这是否符合我的预期)。

      我没有将保存逻辑放在 InsertSomeEntity() 或 UpdateSomeEntity() 方法中,而是在 ExecuteChangeSet 中完成。这是因为 NHibernate,它需要在 NHibernate 中执行操作之前使实体图完全双向并水合。这包括当子项从 RIA 服务通过线路时从数据库或会话加载实体。 (我开始编写方法来获取图表的其他各个部分,因为那些专门的方法需要它们,但我发现在一个方法中完成这一切更容易。此外,我遇到了 RIA 想要的问题我首先对子对象执行插入/更新,这对于新项目是一个问题。)

      我想对 composition 属性发表评论。我仍然坚持我之前关于不推荐它用于标准子实体集合的评论,但是,它对于支持 NHibernate 组件非常有用,因为否则 RIA 将永远不会发回父实例(组合的),这是 NHibernate 工作所必需的对。

      我没有在此处提供任何代码,因为我必须进行一些繁重的编辑,但如果您愿意,我可以这样做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        相关资源
        最近更新 更多