流畅的NHibernate:外键违规或空值

时间:2010-06-14 11:23:54

标签: fluent-nhibernate nhibernate-mapping

嘿伙计们,我在使用流利的nhibernate进行映射方面遇到了一些实际问题。我意识到这个网站上有很多帖子,还有许多其他帖子专注于特定类型的映射,但到目前为止,我还没有找到解决方案来解决我的问题。

这就是我所拥有的:

namespace MyProject.Models.Entites
{
    public class Project
    {
       public virtual Guid Id {get; set;}
       // A load of other properties
       public virtual ProjectCatagory Catagory{get;set;}           
    }
}

然后是地图:

namespace MyProject.DataAccess.ClassMappings
{
    public class ProjectMap : ClassMap<Project>
    {
        public ProjectMap()
        {
            Id(x => x.Id);
            Map(x => x.Title);
            Map(x => x.Description);
            Map(x => x.LastUpdated);
            Map(x => x.ImageData).CustomSqlType("image");
            HasOne(x => x.Catagory);           
        }
    }
}

正如您所看到的,我有一个包含类别属性的项目。我对关系数据库不是那么热,但从我可以想象的,这是一个多关系,许多项目可以有一个类别。不,项目不能属于多个类别。

现在我们有:

namespace MyProject.Models.Entities
{
   public class ProjectCatagory
   {
        public virtual Guid Id { get; set; }
        public virtual String Name { get; set; }
   }
}

及其地图:

public ProjectCatagoryMap()
{
    Id(x => x.Id);
    Map(x => x.Name);
}

问题是,它不起作用!我将在单元测试中做类似以下的事情:

Project myproject = new Project("Project Description");
// set the other properties
myProject.Catagory = new ProjectCatagory(Guid.New(), "Test Catagory");
repository.Save(myProject);

现在,我试图让它工作时尝试了许多映射和数据库配置。目前,Project数据库表有一个列“Catagory_id”(我没有把它放在那里,我假设NH作为映射的结果添加了它),我想它设置为不允许空值。但是,当设置为这样时,我得到异常,解释我无法在表中插入空值(即使在调试期间,我已经检查了Project对象上的所有属性,它们都不为null)。

或者,我可以允许表接受该列中的空值,它只是保存Project对象并在保存时完全忽略Category属性,因此,在检索时,测试以检查是否与正确的类别相关联该项目失败。

如果我没记错的话,有一次我使用了ProjectMap:

References(x => x.Catagory).Column("Catagory_id").Cascade.All().Not.Nullable();

这将“无法插入空值”的异常更改为外键冲突。

我怀疑所有这些麻烦的根源来自于我对关系数据库设置缺乏了解,因为我在这个项目中有其他实体没有外部依赖关系,这对NHibernate非常好,排除了我可能遇到的任何编码问题在创建存储库时引起的。

任何帮助非常感谢。谢谢。

3 个答案:

答案 0 :(得分:3)

这里的主要问题是对关系数据库中的“一对一”关系和Fluent中的HasOne映射的常见误解。映射中的术语是关系术语。 (流利的人试图“美化”它们使IMO变得更糟。HasOne实际上意味着:一对一。)

查看Fluent wiki

  

HasOne通常是为a保留的   特殊情况。一般来说,你会使用一个   参考关系最多   情况(参见:我认为你的意思是   多对的一个)。

解决方案非常简单,只需在HasOneReferencesone-to-one的XML映射文件中交换many-to-one即可。您在数据库中获得引用ProjectCatagory

的外键

关系数据库中真正的一对一关系理想地由主键同步映射。当两个对象共享相同的主键时,您不会为其他外键浪费空间,并且确保它是一对一的。

要同步主键,您需要将其中一个键连接到其他键。无论如何,这不是你需要的。

答案 1 :(得分:0)

在玩完所有可用的映射选项之后。我发现答案与建议的相似。

如所怀疑的,HasOne()显然是错误的,References(x => x.Catagory)是解决方案的一部分。但是,我仍然收到外键违规例外,直到:

References(x => x.Catagory).Column("Catagory_id").Cascade.SaveUpdate().Not.Nullable().Not.LazyLoad();

只是认为id更新了该主题,以防其他人因为使用References()而导致类似问题而无法解决此问题。

答案 2 :(得分:0)

似乎ProjectCatagory类是Project Class的父类。因此,如果没有父类,子类如何存在。

你必须使用 -

参考文献(x =&gt; x.Catagory).Column(“Catagory_id”)。外键(“Id”);

此处外键是您的ProjectCatagory表ID。