Working around awkward values in a legacy table with NHibernate
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, b开发者_JS百科ut 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?
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.
public virtual Category ParentCategory
{
get { return CategoryId == _parentCategory.CategoryId ? null : _parentCategory; }
set { _parentCategory = value ?? this; }
}
精彩评论