开发者

Working around awkward values in a legacy table with NHibernate

开发者 https://www.devze.com 2023-02-07 01:34 出处:网络
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.

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; }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消