使用 NHibernate 解决遗留表中的尴尬值

发布于 2024-10-14 21:54:44 字数 2304 浏览 1 评论 0原文

我刚刚开始使用 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=1parentcategoryid=1)在映射表中。

这让我得到了一个 .Parent 属性,它不断地引用同一个对象。 (所以 .Parent.Parent.Parent.Parent.etc 是同一个对象)

NHibernate 似乎很聪明,最终放弃了,但它大大减慢了速度。

因此,理想情况下,映射的定义方式应为:如果 parentcategoryid=categoryidparentcategoryid=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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萝莉病 2024-10-21 21:54:44

如果可能的话,使用视图过滤掉ID为0的行。

对于第二个问题,将父对象映射为私有字段并公开它,如下例所示。如果该对象与其父对象相同,则返回空父对象。

public virtual Category ParentCategory
{
    get { return CategoryId == _parentCategory.CategoryId ? null : _parentCategory; }
    set { _parentCategory = value ?? this; }
}

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; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文