每当我加载Task类时,尽管db中有数据,Document属性始终为null.
任务类:
public class Task { public virtual Document Document { get; set; }
AutoPersistenceModel的任务映射覆盖:
public void Override(AutoMapmapping) { 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
如果我破解数据库中的数据以便id匹配,则加载数据,但显然这是不正确的 - 但至少证明它加载了数据.
编辑:在流利的nhib源中搜索,找到XML产生这个:
编辑:继承人架构:
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,
有人有任何想法吗?
谢谢
安德鲁
我今天遇到了同样的问题.我相信诀窍不是使用带有.HasOne映射的.ForeignKey(...),而是使用.PropertyRef(...)代替.以下是我如何定义组织(父)与其管理员(子)之间的一对一关系:
HasOne(x => x.Admin).PropertyRef(r => r.Organisation).Cascade.All();
管理员使用其外键对组织进行简单引用:
References(x => x.Organisation, "ORAD_FK_ORGANISATION").Not.Nullable();
检索组织时,这将加载正确的管理记录,并正确级联更新和删除.
你应该使用:
参考文献(x => x.Document,"DocumentIdColumnOnTask")
我认为这里的问题是"HasOne"约定意味着你指的是另一件事(标准的关系方式说"多对一"/"一对一"); 通过在文档上放置一个Task_ID,实际的关系是一个HasMany,但你有一种隐含的理解,即每个任务只有一个文档.
对不起 - 我不知道如何解决这个问题,但我有兴趣了解解决方案是什么(我不使用NHibernate或Fluent NHibernate,但我一直在研究它以便将来使用).解决方案(来自非常少见的人)将使Document成为Task上的集合,然后提供Document属性,该属性返回集合中的第一个(使用隐藏Documents属性的接口,因此没有人认为他们可以添加它的新项目).
查看文档并考虑eulerfx的答案,也许这种方法可能是这样的:
References(x => x.Document) .TheColumnNameIs("ID") .PropertyRef(d => d.Task_ID);
编辑:这样这个答案有适当的解决方案:正确的路径是更新数据库模式以匹配代码的意图.这意味着将DocumentID添加到Task表中,因此Task和Document之间存在多对一关系.如果无法进行架构更改,则References()将是适当的解决方案.