I have to access a legacy database in which I'm faced with the following: A column 'unit_name' is defined as primary key and is a string, and another column 'id' is defined as a classic int identifier.
My question is - how do I map this correct in Fluent NHibernate?
Currently my mapping looks like this, but I can't find any proper documentation for my scenario, so I'm not sure if it is correct.
public InputMap()
{
Table("input");
Map(x => x.unit_name).Not.Nullable().Unique();
//other mappings ...
Id(x => x.id).Column("id").Not.Nullable();
//Maybe use this instead? NaturalId().Property(x => x.unit_name);
}
Full context:
In my hunt for documentation I've created an id class that implements Equals and GetHashCode, but that might be overkill after all.
[Serializable]
public class GenericEntityId : EntityId, IEquatable<GenericEntityId>
{
public GenericEntityId(string idString)
{
IdString = idString;
}
public string IdString { get; set; }
private Guid _internalId { get; set; }
protected GenericInoEntityId()
{
_internalId = Guid.NewGuid();
}
public virtual bool Equals(GenericEntityId obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (GetType() != obj.GetType()) return false;
if (!string.IsNullOrEmpty(IdString) )
return obj.IdString == IdString;
return false;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (GetType() != obj.GetType()) return false;
return Equals((GenericEntityId)obj);
}
public override int GetHashCode()
{
if (!string.IsNullOrEmpty(IdString))
{
return (IdString.GetHashCode() * 397) ^ GetType().GetHashCode();
}
else
{
return (_internalId.GetHashCode() * 397) ^ GetType().GetHashCode();
}
}
public static bool operator ==(GenericEntityId left, GenericEntityId right)
{
return Equals(left, right);
}
public static bool operator !=(GenericEntityId left, GenericEntityId right)
{
return !Equals(left, right);
}
}
and EntityId is just an abstract class:
public abstract class EntityId
{
public abstract override int GetHashCode();
}
The reason for creating an abstract base is that I want to have a generic base I can use for all my repositories no matter if they have a string primary key or a composite key (or maybe the identifier)
[Serializable]
public abstract class EntityBase
{
public abstract EntityId entityId { get; }
protected EntityBase()
{
}
}
public class GenericRepository<TEntity> : SessionManagerBase, IEntityRepository<TEntity> where TEntity : EntityBase
{
public TEntity GetById(EntityId id)
{
ISession currentSession = OpenSession;
var returnObject = currentSession.Get<TEntity>(id);
return returnObject;
}
}
This is Nhibernate mapping-by-code, but fluent should be similar
domain object class
public class TestEntity
{
public String unit_name { get; set; }
public Int32 id { get; protected set; }
}
mapping class
public class TestEntityMap : ClassMapping<TestEntity>
{
public TestEntityMap()
{
Id( x => x.unit_name, map =>
{
map.Column("user_name");
map.Generator(Generators.Assigned);
});
Property(x => x.id, map =>
{
map.Generated(PropertyGeneration.Always);
map.Unique(true);
map.NotNullable(true);
});
}
}