【问题标题】:fluent nhibernate HasOne WithForeignKey not working流利的休眠 HasOne WithForeignKey 不起作用
【发布时间】:2010-10-13 05:17:33
【问题描述】:

每当我加载一个 Task 类时,Document 属性始终为 null,尽管 db 中有数据。

任务类:

public class Task
{
    public virtual Document Document { get; set; }

AutoPersistenceModel 的任务映射覆盖:

public void Override(AutoMap<Task> mapping)
{
    mapping.HasOne(x => x.Document)
        .WithForeignKey("Task_Id");

正如您所见,NHProf 所说的正在运行,连接条件错误,WithForeignKey 似乎没有生效。事实上,我可以在上面的代码中写任何字符串,它没有任何区别。

FROM   [Task] this_
    left outer join [Document] document2_
    on this_.Id = document2_.Id

应该是:

FROM   [Task] this_
    left outer join [Document] document2_
    on this_.Id = document2_.Task_Id

如果我破解数据库中的数据以使 ids 匹配,则加载数据,但显然这是不正确的 - 但至少它证明它加载了数据。

编辑:在流畅的 nhib 源中翻找 XML 会产生这样的结果:

<one-to-one foreign-key="Task_Id" cascade="all" name="Document" class="MyProject.Document, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 

编辑:这是架构:

CREATE TABLE [dbo].[Document](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Task_Id] [int] NOT NULL,

CREATE TABLE [dbo].[Task](
[Id] [int] IDENTITY(1,1) NOT NULL,

有人有什么想法吗?

谢谢

安德鲁

【问题讨论】:

    标签: fluent-nhibernate


    【解决方案1】:

    我试过这个解决方案:

    就在文档中:

    mapping.HasOne(x => x.Task).ForeignKey("Task_ID").Constrained().Cascade.All();
    

    【讨论】:

      【解决方案2】:

      我一直在为同样的 Has One 问题苦苦挣扎,终于发现这行得通:

      public class ParentMap : ClassMap<Parent>
      {
          public ParentMap()
          {
              Id(x => x.Id);
              HasOne(s => s.Child).Cascade.All();
          }
      }
      
       public class ChildMap : ClassMap<Model.Child>
      {
          public ChildMap()
          {
              Id(x => x.Id);
              HasOne(s => s.Parent).Constrained().ForeignKey();           
          }
      }
      

      【讨论】:

      • 两个表中的compositeid怎么办?
      【解决方案3】:

      我今天遇到了同样的问题。我相信诀窍不是将 .ForeignKey(...) 与 .HasOne 映射一起使用,而是使用 .PropertyRef(...) 。以下是我如何定义组织(父)与其管理员(子)之间的一对一关系:

      HasOne(x => x.Admin).PropertyRef(r => r.Organisation).Cascade.All();
      

      管理员使用其外键对组织进行简单引用:

      References(x => x.Organisation, "ORAD_FK_ORGANISATION").Not.Nullable();
      

      在检索组织时,这将加载正确的管理员记录,并正确地级联更新和删除。

      【讨论】:

      • 似乎完美的答案是这个和 Chris Shaffer 的答案的结合。这个答案提供了一个使用 Fluent NHibernate 的工作实现,而 Chris Shaffer 提供了一些关于为什么初始实现不起作用的“理论”。
      • 也为我工作,非常感谢。但是 HasOne().ForeignKey() 是什么?
      • +1 但我必须将引用写为 References(x => x.Organisation).ForeignKey("ORAD_FK_ORGANISATION").Not.Nullable();因为它将外键名称作为组织的列名
      【解决方案4】:

      我认为这里的问题是“HasOne”约定意味着您指向另一件事(说“多对一”/“一对一”的标准关系方式);通过将 Task_ID 放在文档上,实际关系是 HasMany,但您有某种隐含的理解,即每个任务只会有一个文档。

      抱歉 - 我不知道如何解决这个问题,但我有兴趣了解解决方案是什么(我不使用 NHibernate 或 Fluent NHibernate,但我一直在研究它以供将来使用)。一个解决方案(来自一个几乎没有想法的人)是让 Documents 成为 Task 上的一个集合,然后提供一个 Document 属性,该属性返回集合中的第一个(使用隐藏 Documents 属性的界面,因此没有人认为他们可以添加新项目)。

      查看文档并考虑 eulerfx 的答案,也许方法类似于:

      References(x => x.Document)
          .TheColumnNameIs("ID")
          .PropertyRef(d => d.Task_ID);
      

      编辑:这个答案有适当的解决方案:正确的路径是更新数据库模式以匹配代码的意图。这意味着将 DocumentID 添加到 Task 表中,因此 Task 和 Document 之间存在多对一的关系。如果无法更改架构,References() 将是合适的解决方案。

      【讨论】:

      • 我同意这种可能性,但为什么 Task_Id 没有在任何地方呈现? (即使它是错误的,因此会导致异常 - 但它不会)
      • 这确实有效,但这意味着我需要 Document 上的 Task_id 属性,我宁愿没有。虽然现在可以工作,但谢谢
      【解决方案5】:

      正如 eulerfx 指出的那样,

      表格结构表明一个任务可能有多个文档

      克里斯说:

      通过将 Task_ID 放在文档上,实际关系是 HasMany,但您有某种隐含的理解,即每个任务只有一个文档。

      这当然是正确的,所以我把它反转了,所以 Task 有一个可为空的 Document_Id。

      感谢两位的帮助!

      我投了一枚硬币以获得接受的答案,如果我能同时勾选我会的!

      【讨论】:

      • 嘿,安德鲁,PLN 的答案是肯定的。我会说,通过重新做数据库,你实际上做了正确的事情。但有时您无法更改数据库,而这正是 Fluent Mappings 真正大放异彩的地方。 HasOne 就是这样一个功能,你和我都错误地使用了它。 PLN 指出了使用它的正确方法......我的 2 美分
      【解决方案6】:

      你应该使用:

      参考(x => x.Document, "DocumentIdColumnOnTask")

      【讨论】:

      • tblDocument 有 Task_Id,而不是 tblTask​​ 有 Document_Id
      • 哦,好吧,错过了那部分。然后我想在任务表上有一个 docID 是最有意义的。否则表结构表明一个任务可能有多个文档。
      • 是的,我想是的。这是有原因的,但我不记得为什么。我会考虑并考虑扭转它。 ta
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-28
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多