我正在尝试创建一个鉴别符列。该列将包含许多可用状态之一。就像我的代码将显示的那样,每个状态都有一个名称以及背景色。每个状态共享相同的基类。
这是我的代码:
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
列的值将为1。我现在不会抛出任何异常,但是它总是插入[ C0]作为ItemStatus
。
这是我正在使用的插入代码:
0
我可以在哪里使用FNH阅读此主题?
在有人建议使用Google之前,我确实搜索了几件事,但是我找不到一个完整的例子。
您的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);
}
看起来像这样:
SubclassMap
这被称为“每类表层次结构”,您说对了,看起来那里没有很多资源。
I believe,如果您没有在public class FooStatusMap : SubclassMap<FooStatus>
{
public FooStatusMap()
{
DiscriminatorValue(1);
}
}
中调用DiscriminatorValue
,则NHibernate尝试通过查看要映射的子类的名称并查看其是否与discriminator列中的值匹配来进行区分。
我不会为所有子类编写子映射,而只需执行此操作
SubclassMap
希望有所帮助
如果您打开包含派生类的类名称的Discriminator列,则可以通过自动映射实现。
在您的会话工厂中:
public class FooMap: ClassMap<T>
{
//other mapping
DiscriminateSubClassesOnColumn("DiscriminatorColumn")
.SubClass<Foo1>(m => { })
.SubClass<Foo2>(m => { })
.SubClass<Foo3>(m => { });
}
然后添加MyMappingConfiguration覆盖:
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