使用 NHibernate 解决遗留表中的尴尬值
我刚刚开始使用 NHibernate,我正在尝试加入一个旧表,该表使用 0
值而不是 NULL
来表示某些内容不存在。
数据库中还有一行 id 为 0
的行,它只是一个占位符。
我想避免检索此占位符,而是希望我的属性显示为 null
。
我尝试创建一个 IUserType
来处理将 0
的值映射到 null
并返回,但我不认为多对一(.References()
) 映射适用于自定义类型。
这是类:
public class Category
{
public virtual int Id { get; set; }
public virtual string CategoryName { get; set; }
public virtual Category Parent { get; set; }
public virtual IList<Category> Children { get; set; }
public virtual Category RealCategory { get; set; }
public virtual bool IsHomeParent { get; set; }
}
这是映射:
public class CategoryMapping:ClassMap<Category>
{
public CategoryMapping()
{
Id(x => x.Id);
Map(x => x.CategoryName);
Join("categorymappings",
m =>
{
m.KeyColumn("categoryid");
m.Map(z => z.IsHomeParent);
// need ids of 0 to come up as null for .Parent
m.References(z => z.Parent).Column("parentcategoryid");
m.References(z => z.RealCategory).Column("realcategoryid").Not.LazyLoad();
m.Optional();
});
HasManyToMany(p => p.Children)
.Table("categorymappings")
.ParentKeyColumn("parentcategoryid")
.ChildKeyColumn("categoryid")
.Where("ishomeparent=0")
.Fetch.Join()
.Not.LazyLoad();
Table("categories");
}
}
所以,再说一次。我正在尝试将 0
的 id 的 .Parent
设为 null
。
与此相关的是,遗留数据库中的数据还存在无限递归问题,我需要避免这一问题。
当类别位于最顶层时,categoryid
等于 parentcategoryid
(例如,categoryid=1
、parentcategoryid=1
)在映射表中。
这让我得到了一个 .Parent 属性
,它不断地引用同一个对象。 (所以 .Parent.Parent.Parent.Parent.etc
是同一个对象)
NHibernate 似乎很聪明,最终放弃了,但它大大减慢了速度。
因此,理想情况下,映射的定义方式应为:如果 parentcategoryid=categoryid
或 parentcategoryid=0
,则 .Parent
列为忽略(设置为 null
)。
这可以通过 Fluent 映射来完成吗?
I'm just starting out with NHibernate and I'm trying to join against a legacy table that uses values of 0
instead of NULL
to represent something doesn't exist.
There's also a row with an id of 0
in the database which is simply a placeholder.
I'd like to avoid retrieving this placeholder, and instead I want my property to come up as null
.
I tried making an IUserType
to handle mapping the value of 0
to null
and back, but I'don't think Many-To-One (.References()
) mappings work with custom types.
This is the class:
public class Category
{
public virtual int Id { get; set; }
public virtual string CategoryName { get; set; }
public virtual Category Parent { get; set; }
public virtual IList<Category> Children { get; set; }
public virtual Category RealCategory { get; set; }
public virtual bool IsHomeParent { get; set; }
}
This is the mapping:
public class CategoryMapping:ClassMap<Category>
{
public CategoryMapping()
{
Id(x => x.Id);
Map(x => x.CategoryName);
Join("categorymappings",
m =>
{
m.KeyColumn("categoryid");
m.Map(z => z.IsHomeParent);
// need ids of 0 to come up as null for .Parent
m.References(z => z.Parent).Column("parentcategoryid");
m.References(z => z.RealCategory).Column("realcategoryid").Not.LazyLoad();
m.Optional();
});
HasManyToMany(p => p.Children)
.Table("categorymappings")
.ParentKeyColumn("parentcategoryid")
.ChildKeyColumn("categoryid")
.Where("ishomeparent=0")
.Fetch.Join()
.Not.LazyLoad();
Table("categories");
}
}
So, again. I'm trying to get .Parent
to be null
for ids of 0
.
On a related note, there's also an infinite recursivity issue with the data in the legacy database which I need to avoid.
When the category is at the top-most level, categoryid
is equal to parentcategoryid
(eg. categoryid=1
, parentcategoryid=1
) in the mapping table.
That gets me a .Parent property
that keeps referencing the same object over and over. (so .Parent.Parent.Parent.Parent.etc
is the same object)
NHibernate seems to be smart enough to give up eventually, but it's slowing things down considerably.
So, ideally the mapping should be defined in such a way that if either parentcategoryid=categoryid
or if parentcategoryid=0
, the .Parent
column is ignored (set to null
).
Can this be done with Fluent mappings?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果可能的话,使用视图过滤掉ID为0的行。
对于第二个问题,将父对象映射为私有字段并公开它,如下例所示。如果该对象与其父对象相同,则返回空父对象。
If possible, use a view to filter out the row with an ID of 0.
For the second problem, map the parent object as a private field and expose it like the example below. This returns a null parent if the object and its parent are the same.