How do I exclude a base class using fluent mappings in Fluent NHibernate? - fluent-nhibernate

I have an abstract base class, Entity, that all my POCOs derive from:
public abstract class Entity
{
public virtual Guid Id { get; set; }
}
And the mapping file:
public class EntityMap<T> : ClassMap<T> where T : Entity
{
public EntityMap
{
Id(x => x.Id);
}
}
This way, I don't have to write Id(x => x.Id) in every mapping file by using this:
public class Something : EntityMap<T>
{
blahblah
}
I'm auto-generating my database schema, and everything looks fine, except that the Entity base class is added as a table. Using fluent mappings, how do I configure it so that the Entity class is excluded from the database schema?

You can add it to the ignore list of auto mapper:
AutoMap.AssemblyOf<Entity>()
.IgnoreBase(typeof(Entity));

Related

Mapping a collection of Interface with NHibernate Mapping ByCode

With FluentNHibernate I mapped a collection of interface by specifying the concrete type in the mapping class. I'm trying to convert to Maping.ByCode.
Entity classes:
public class Parent Entity
{
public virtual Guid Id{get;set;}
public virtual IList<IChildEntity> Children{get;set;}
}
public class ChilEntity:IChildEntity
{
public virtual Guid Id{get;set;}
}
With FluentNHibernate:
public class ParentEntityMap:ClassMap<ParentEntity>
{
public ParentEntityMap()
{
Table("ParentEntity");
Id(x => x.Id);
HasMany<ChildEntity>(x=>x.Children)
.KeyColumn("Parent");
}
}
With Mapping ByCode:
public class ParentEntityMap:ClassMapping<ParentEntity>
{
Public ParentEntityMap()
{
Table("ParentEntity");
Id(x=>x.Id);
Bag<ChildEntity>(x=>(IList<ChildEntity>)x.Children,
m=>m.Key(k=>k.Column("Parent")),
ce=>ce.OneToMany()
);
The mapping ByCode doesn't work. Is there a way to achieve what is done with Fluent NHibernate?
Try setting Class:
Bag(x=>x.Children,
m=> m.Key(k=>k.Column("Parent")),
ce=> ce.OneToMany(m => m.Class(typeof(ChildEntity)))
);

Map list of items

I have a table called openTickets. I have another table called openTicketFollowers that relates to it using a foreign key. OpenTickets does not know about openTicketFollowers but I want openTickets to have a property that is a list of its followers. Is there anyway to do this with fluent nhibernate?
Check this Fluent mapping document. The OpenTicket class will contain IList of Followers:
public class OpenTicket
{
...
public virtual IList<OpenTicketFollower> Followers { get; set; }
}
public class OpenTicketFollowers
{
public virtual OpenTicket OpenTicket { get; set; }
}
And this is fluent mapping of the OpenTicketFollowercollection:
HasMany(x => x.Followers)
.KeyColumn("OpenTicketId");
and the OpenTicketFollower class mapping referencing the OpenTicket
References(x => x.OpenTicket)
.Column("OpenTicketId")

Fluent NHibernate and per-subclass inheritance

I have a Base class and two childs (A:Base and B:Base), and I want to map them to two tables (table A and table B). Is that possible in Fluent NHibernate? So I have:
public class Base
{
public virtual int Id {get;set;}
public virtual int IndexIn {get;set;}
public virtual Product Product {get;set;}
}
public class A : Base
{
public virtual string Value {get;set;}
}
public class B : Base
{
public virtual int Value {get;set;}
public virtual IList<Sequence> Sequences {get;set;}
}
My mapping is:
public class BaseMap : ClassMap<Base>
{
public BaseMap()
{
Id(x => x.Id);
Map(x => x.IndexIn);
References(x => x.Product);
}
}
public class AMap : SubclassMap<A>
{
public AMap()
{
Map(x => x.Value);
}
}
public class BMap : SubclassMap<B>
{
public BMap()
{
Map(x => x.Value);
HasMany(x => x.Sequences);
}
}
But in that case it creates three tables (A, B and Base). That's nice, but I need to reduce number of tables, so I am ok to have Base's fields in both A and B table. Generally I want to simply map A and B as normal classes (without using inheritance), but I need to be able to add some other class, where I can have property:
public virtual IList<Base> ListofAandB {get;set;}
If I remove BaseMap definition and just map A and B as ClassMap<> I receive error "Cannot find map definition for Base" if I try to use the property that is written above.
You won't be able to map your ListOfAAndB property if your inheritance is present only in your code and not in your database model. To have NHibernate map this property as it is defined, you are going to need a Base table in your database.

Mapping class hierarchy through fluent nhibernate by using 2 strategies

I want to combine table-per-class and table-per-hierarchy strategies using fluent nhibernate or nhibernate itself(I mean hbm files), but I don't know how. I prefer fluent over hbm but if it's impossible, then hbm is also fine. I tested this by introducing Entity as ClassMap and all other as SubClassMap in fluent but then in hbm files generated by fluent, Entity was a class and all other were joined-classes which is not what I want. I will describe the problem in more detail below.
Class hierarchy:
public class Entity
{
public int ID { get; set; }
public string Name { get; set; }
}
public abstract class Person : Entity
{
public string Phone { get; set; }
}
public class SystemUser : Person
{
public string Password { get; set; }
}
I want to have one table for entity and one for person and all kinds of it(all its subclasses).I mean I want to use table-per-class strategy for Entity and table-per-hierarchy strategy for Person and SystemUser classes. Database structure is something like this:
EntityTable(ID(PK),Name)
PersonTable(EntityID(PK,FK),Phone,Password)
any help appreciated.
if EntityTable Id is not database generated (which is discouraged by NH anyways) you can use the trick
public PersonMap : ClassMap<Person>
{
public PersonMap()
{
Table("PersonTable");
Id(p => p.Id, "EntityID").GeneratedBy.HiLo("100");
DiscriminateSubClassesOnColumn("PersonType");
Map(x => x.Phone);
Join("EntityTable", join =>
{
join.KeyColumn("ID");
join.Map(p => p.Name);
});
}
}
public SystemUserMap : SubclassMap<SystemUser>
{
public SystemUserMap()
{
Map(x => x.Password);
}
}

Fluent Nhibernate How to specify Id() in SubclassMap

I'm in the process of adapting Fluent NHibernate to our existing legacy app and am trying to determine how to use ClassMap and SubclassMap for the entity hierarchy shown.
// BaseObject contains database columns common to every table
public class BaseObject
{
// does NOT contain database id column
public string CommonDbCol1 { get; set; }
public string CommonDbCol2 { get; set; }
// ...
}
public class Entity1 : BaseObject
{
public int Entity1Id { get; set; }
// other Entity1 properties
}
public class Entity2 : BaseObject
{
public int Entity2Id { get; set; }
// other Entity2 properties
}
The identity columns for Entity1 and Entity2 are uniquely named per table. BaseObject contains columns that are common to all of our entities. I am not using AutoMapping, and thought I could use ClassMap on the BaseObject, and then use SubclassMap on each Entity like this:
public class Entity1Map : SubclassMap<Entity1>
{
public Entity1Map()
{
Id(x => x.Entity1Id);
// ...
}
}
Problem is, Id() is not defined for SubclassMap. So, how do I specify within each Entity1Map, Entity2Map, ... (we have 100+ entity classes all inheriting from BaseObject) what the entity-specific Id is?
Thanks in advance for any insight!
It's not possible to do that in either Fluent NHibernate or NHibernate. Do you actualy want your classes to be mapped as subclasses, or do you just want them to share the common mappings? If you truly want subclasses, then you're going to need to have them share the identity column, no other way around it; if you don't want actual subclasses, create an abstract ClassMap<T> where T : BaseObject and map the common properties in there.
Something like:
public abstract class BaseObjectMap<T> : ClassMap<T> where T : BaseObject
{
public BaseObjectMap()
{
Map(x => x.CommonProperty1);
}
}