在 Fluent NHibernate 中使用鉴别器

发布于 2024-11-27 04:22:29 字数 2178 浏览 1 评论 0原文

我正在尝试创建一个鉴别器列。该列将保存许多可用状态之一。就像我的代码将显示的那样,每个状态都有一个名称和背景颜色。每个状态共享相同的基类。

这是我的代码:

public class Item
{
    public virtual int Id { get; set; }
    public virtual Status ItemStatus { get; set; }
}

public abstract class Status
{
    private readonly int _id;
    public static readonly Status Foo = new FooStatus(1);
    public static readonly Status Bar = new BarStatus(2);

    public Status()
    {

    }

    protected Status(int id)
    {
        _id = id;
    }

    public virtual int Id { get { return _id; } }
    public abstract string Name { get; }
    public abstract string BackgroundColor { get; }
}

public class FooStatus : Status
{
    public FooStatus()
    {

    }

    public FooStatus(int id)
        : base(id)
    {

    }

    public override string Name
    {
        get { return "Foo Status"; }
    }

    public override string BackgroundColor
    {
        get { return "White"; }
    }
}

public class BarStatus : Status
{
    public BarStatus()
    {

    }

    public BarStatus(int id)
        : base(id)
    {

    }

    public override string Name
    {
        get { return "Bar Status"; }
    }

    public override string BackgroundColor
    {
        get { return "Black"; }
    }
}

这是我的映射:

public class ItemMap : ClassMap<Item>
{
    public ItemMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();

        DiscriminateSubClassesOnColumn<int>("ItemStatus", 0).AlwaysSelectWithValue();
    }
}

本质上,我想要的是,如果我将 ItemStatus 设置为 Status.Foo,则 ItemStatus code> 列的值为 1。我现在所拥有的不会引发任何异常,但它总是将 ItemStatus 插入为 0

这是我正在使用的插入代码:

using (var session = sessionFactory.OpenSession())
using (var transaction = session.BeginTransaction())
{
    var item = new Item
    {
        ItemStatus = Status.Foo
    };
    session.Save(item);
    transaction.Commit();

    var firstItem = session.Get<Item>(1);
    Console.WriteLine(firstItem.ItemStatus.Name);
}

Where can I read up on this topic using FNH?

在有人建议检查谷歌之前,我确实搜索了一些东西,但我找不到完整的例子。

I'm trying to create a discriminator column. This column would hold one of the many statuses available. Like my code will show, each status has a name as well as a background color. Each status shares the same base class.

Here is my code:

public class Item
{
    public virtual int Id { get; set; }
    public virtual Status ItemStatus { get; set; }
}

public abstract class Status
{
    private readonly int _id;
    public static readonly Status Foo = new FooStatus(1);
    public static readonly Status Bar = new BarStatus(2);

    public Status()
    {

    }

    protected Status(int id)
    {
        _id = id;
    }

    public virtual int Id { get { return _id; } }
    public abstract string Name { get; }
    public abstract string BackgroundColor { get; }
}

public class FooStatus : Status
{
    public FooStatus()
    {

    }

    public FooStatus(int id)
        : base(id)
    {

    }

    public override string Name
    {
        get { return "Foo Status"; }
    }

    public override string BackgroundColor
    {
        get { return "White"; }
    }
}

public class BarStatus : Status
{
    public BarStatus()
    {

    }

    public BarStatus(int id)
        : base(id)
    {

    }

    public override string Name
    {
        get { return "Bar Status"; }
    }

    public override string BackgroundColor
    {
        get { return "Black"; }
    }
}

And here is my mapping:

public class ItemMap : ClassMap<Item>
{
    public ItemMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();

        DiscriminateSubClassesOnColumn<int>("ItemStatus", 0).AlwaysSelectWithValue();
    }
}

Essentially, what I'd like is that if I set ItemStatus to Status.Foo then the ItemStatus column would have a value of 1. What I have now doesn't throw any exceptions, but it always inserts ItemStatus as 0.

This is the inserting code I'm using:

using (var session = sessionFactory.OpenSession())
using (var transaction = session.BeginTransaction())
{
    var item = new Item
    {
        ItemStatus = Status.Foo
    };
    session.Save(item);
    transaction.Commit();

    var firstItem = session.Get<Item>(1);
    Console.WriteLine(firstItem.ItemStatus.Name);
}

Where can I read up on this topic using FNH?

Before anyone suggests be to check on Google I did search several things but nowhere can I find a full example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

惟欲睡 2024-12-04 04:22:29

您的 SubclassMap 看起来像这样:

public class FooStatusMap : SubclassMap<FooStatus>
{
    public FooStatusMap()
    {
        DiscriminatorValue(1);
    }
}

这称为“每个类层次结构表”,您是对的,它看起来没有很多资源。

相信如果你不在SubclassMap中调用DiscriminatorValue,NHibernate会尝试通过查看被映射的子类的名称并查看来进行区分如果它与鉴别器列中的值匹配。

Your SubclassMap would look something like this:

public class FooStatusMap : SubclassMap<FooStatus>
{
    public FooStatusMap()
    {
        DiscriminatorValue(1);
    }
}

This is called "table-per-class-hierarchy," and you're right it doesn't look like there are many resources on it out there.

I believe if you don't call DiscriminatorValue in a SubclassMap, NHibernate attempts to discriminate by looking at the name of the subclass being mapped and seeing if it matches up with the value in the discriminator column.

菊凝晚露 2024-12-04 04:22:29

我不会为所有子类编写子图,你可以这样做

public class FooMap: ClassMap<T>
{
//other mapping
DiscriminateSubClassesOnColumn("DiscriminatorColumn")
.SubClass<Foo1>(m => { })
.SubClass<Foo2>(m => { })
.SubClass<Foo3>(m => { });
}

希望有帮助

I wouldnt write submaps for all the subclasses you can just do this instead

public class FooMap: ClassMap<T>
{
//other mapping
DiscriminateSubClassesOnColumn("DiscriminatorColumn")
.SubClass<Foo1>(m => { })
.SubClass<Foo2>(m => { })
.SubClass<Foo3>(m => { });
}

Hope that helps

暗地喜欢 2024-12-04 04:22:29

如果您愿意使用具有派生类的类名的鉴别器列,则可以通过自动映射来实现这一点。

在您的会话工厂中:

private static ISessionFactory CreateSessionFactory()
{
    var cfg = new MyMappingConfiguration();
    return Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("MyConnectionKey")).FormatSql().ShowSql()
            )
    .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Status>(cfg)
    .IncludeBase<Status>()
    .Conventions.Add<PrimaryKeyConvention>()))
    .BuildSessionFactory();
}

然后添加 MyMappingConfiguration 覆盖:

public class MappingConfiguration : DefaultAutomappingConfiguration
{
    public override bool IsId(Member member)
    {
        return member.Name == member.DeclaringType.Name + "Id";
    }

    public override bool IsDiscriminated(Type type)
    {
        return true;
    }
}

希望 h

If you're open to the Discriminator column having the class names of the derived classes, you can implement this via automapping.

In your session factory:

private static ISessionFactory CreateSessionFactory()
{
    var cfg = new MyMappingConfiguration();
    return Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("MyConnectionKey")).FormatSql().ShowSql()
            )
    .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Status>(cfg)
    .IncludeBase<Status>()
    .Conventions.Add<PrimaryKeyConvention>()))
    .BuildSessionFactory();
}

Then add the MyMappingConfiguration override:

public class MappingConfiguration : DefaultAutomappingConfiguration
{
    public override bool IsId(Member member)
    {
        return member.Name == member.DeclaringType.Name + "Id";
    }

    public override bool IsDiscriminated(Type type)
    {
        return true;
    }
}

Hope that h

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