Using the discriminator with Fluent NHibernate

I am trying to create a discriminator column. This column will contain one of the many available statuses. As in my code, each status has a name, as well as a background color. Each state has 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, I would like if I set ItemStatus to Status.Foo , then the ItemStatus column ItemStatus have a value of 1. What I have now does not throw any exceptions, but always inserts ItemStatus as 0 .

This is the input 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 this topic using FNH?

Before anyone suggests checking on Google, I searched for a few things, but no where can I find a complete example.

+4
source share
3 answers

Your SubclassMap will look something like this:

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

This is called "table-per-class-hierarchy", and you're right, but it doesn't seem to have many resources on it.

I believe that if you do not call DiscriminatorValue in the SubclassMap , NHibernate tries to recognize by looking at the name of the subclass being displayed and seeing if it matches the value in the discriminator column.

+3
source

I would not write subpatterns for all subclasses that you can just do instead

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

Hope that helps

0
source

If you are open to a Discriminator column that has class names of derived classes, you can implement this by auto-tuning.

In the factory session:

 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 an override to 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; } } 

Hope h

0
source

All Articles