使用Fluent-NHibernate的鉴别器

使用Fluent-NHibernate的鉴别器,fluent-nhibernate,Fluent Nhibernate,我正在尝试创建一个鉴别器列。此列将保存许多可用状态之一。就像我的代码将显示的那样,每个状态都有一个名称和背景色。每个状态共享相同的基类 这是我的密码: public class Item { public virtual int Id { get; set; } public virtual Status ItemStatus { get; set; } } public abstract class Status { private readonly int _id;

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

这是我的密码:

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();
    }
}
在哪里可以使用FNH阅读此主题


在任何人建议查看Google之前,我确实搜索了一些东西,但没有找到完整的示例。

您的
子类映射将如下所示:

public class FooStatusMap : SubclassMap<FooStatus>
{
    public FooStatusMap()
    {
        DiscriminatorValue(1);
    }
}
公共类FooStatusMap:子类映射
{
公共状态映射()
{
鉴别器值(1);
}
}
这称为“每个类的表层次结构”,您是对的,它上面看起来没有太多资源


我相信,如果您不在
子类映射中调用
DiscriminatorValue
,NHibernate会通过查看被映射的子类的名称并查看其是否与discriminator列中的值匹配来进行区分。

我不会为所有子类编写子映射,您可以这样做

public class FooMap: ClassMap<T>
{
//other mapping
DiscriminateSubClassesOnColumn("DiscriminatorColumn")
.SubClass<Foo1>(m => { })
.SubClass<Foo2>(m => { })
.SubClass<Foo3>(m => { });
}
公共类FooMap:ClassMap
{
//其他映射
DiscriminateSubClassesOnColumn(“DiscriminatorColumn”)
.子类(m=>{})
.子类(m=>{})
.子类(m=>{});
}

希望这对您有所帮助

如果您打开了包含派生类的类名的鉴别器列,您可以通过自动映射实现这一点

在会话工厂中:

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();
}

希望h

啊,我错过了。当我为每个状态创建子类映射时,NHibernate仍然将
0
作为我的
ItemStatus
插入。这一定是因为我将
baseClassDiscriminator
设置为0。但是,如果在生成配置时删除
baseClassDiscriminator
NHibernate抛出异常“无法将鉴别器值格式化为实体NHibernateDiscriminator.Domain.Item的SQL字符串”。@User:有趣。我将设置这个映射,看看是否可以复制它。@用户:在数据库中,数据类型是整数吗?数据库数据类型是整数。假设它是通过使用
DiscriminateSubClassesOnColumn**
@设置的用户:实际上,再次查看代码时,您需要为基本
状态
类型定义一个映射,并将
DiscriminateSubClassesOnColumn
代码放在那里(不在ItemMap中)。然后为每个子类型定义一个子类映射。我最初的实现是使用这种方法,但它已经过时了。
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();
}
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;
    }
}