嘿伙计们,我在使用流利的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非常好,排除了我可能遇到的任何编码问题在创建存储库时引起的。
任何帮助非常感谢。谢谢。
答案 0 :(得分:3)
这里的主要问题是对关系数据库中的“一对一”关系和Fluent中的HasOne
映射的常见误解。映射中的术语是关系术语。 (流利的人试图“美化”它们使IMO变得更糟。HasOne
实际上意味着:一对一。)
查看Fluent wiki:
HasOne通常是为a保留的 特殊情况。一般来说,你会使用一个 参考关系最多 情况(参见:我认为你的意思是 多对的一个)。
解决方案非常简单,只需在HasOne
(References
到one-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。