I have a model library that I want to automatically build its NHibernate mappings using FluentNhibernate.
There's a convention that I'd like to add to this model and that is each table name ends with 's'.
So here's what I do :
new AutoPersistenceModel()
.AddEntityAssembly(typeof(User).Assembly)
.Conventions.Add(typeof(ClassConvention))
.WriteMappingsTo(#"E:\Temp\");
Here's the code of ClassConvention :
private class ClassConvention:IClassConvention
{
public void Apply(IClassInstance instance)
{
instance.Table(instance.EntityType.Name+"s");
}
}
but it simply doesn't work.No table attribute is added to class tag when I run this code.
Please help me understand what's wrong with my code ?
Update:
I have debugged my code and I am sure that this line :
instance.Table(instance.EntityType.Name+"s");
is called.
Your convention defining class should be public not private
Related
I have the inheritance described below :
public abstract class BaseEntity<TId> {....}
public abstract class ModelEntity : BaseEntity<Int32>{....}
public abstract class AuditableEntity : ModelEntity,IAuditable{....}
public class ApplicationUser : AuditableEntity{....}
public class SuperUser : ApplicationUser
I am using NHibernate 3.3 and I want to Create the mappings for that inheritance
public abstract class ModelEntityMap<TEntity> : ClassMapping<TEntity>
where TEntity : ModelEntity
{...}
public class AuditableEntityMap<TEntity> : ModelEntityMap<TEntity> where TEntity : AuditableEntity
{ ...}
public class ApplicationUserMap : AuditableEntityMap<ApplicationUser>
{...}
public class SuperUserMap : JoinedSubclassMapping<SuperUser>{...}
When the application starts and trys to set up the database it raises the following Exception :
Ambiguous mapping for SuperUser More than one root entities was found BaseEntity / ApplicationUser
Possible solutions
-Merge the mapping of root Entity in the one is representing the real root in the hierarchy
-Inject a IModelInspector with a logic to discover the real root-entity.
I was using Fluent nhibernate with the same inheritance and worked fine with SuperUserMap defined as
public class SuperUserMap : SubClassMap {...}
I am new to Nhibernate mapping by code and quite confused !!!
I believe there are two ways to solve this problem:
a) Using the concept of discriminator that identifies the type of the class stored and thereby the right object is retrieved from the database, in this case your class is mapped to a table that has all the columns plus the discriminator columns. Not sure how this works with multi-level inheritance but this is something that you can google.
b) take a look at this post on how he deals with inheritance: http://fabiomaulo.blogspot.co.nz/2011/04/nhibernate-32-mapping-by-code_13.html you might get some idea to solve your issue.
You can influence the decision whether an entity is a root entity by overriding the IsRootEntity logic of the model mapper that you use to create mappings.
Here's an example that defines the default NHibernate mapping-by-code behaviour:
var modelMapper = new ConventionModelMapper();
modelMapper.IsRootEntity((type, declared) =>
{
if (declared) return true; // Type has already been declared as root entity
return type.IsClass
&& typeof(object) == type.BaseType
&& modelMapper.ModelInspector.IsEntity(type);
});
You will have to tweak this decision logic to exclude the BaseEntity class as possible root entity.
I had this error with NHibernate 4.1.1 (May 2017), so I'm answering with how I solved it for future reference
In my case, I copied an existing mapping of an inheriting class, and forgot to change the parent mapping class to ClassMapping and encountered the same error
In other words, in your mapping class, check the parent class, make sure it is ClassMapping or JoinedSubclassMapping if it's a child class
This is my first time trying Fluent NHibernate and Auto mapping. Unfortunately I have run into an issue that I cannot get past. I'm getting an error saying that a method on one of my classes cannot be mapped.
public class Person
{
public IEnumerable<string> GetStuff(){return stuff;}
}
The Exception Message is:
The entity '<GetStuff>d__0' doesn't have an Id mapped.
I even tried adding an IAutoMappingOverride to ignore the method (using map.IgnoreProperty).
Is it really trying to map a method? whats going on here?
Every entity that you want to Automap must have an Id property, or inherit from a class that has an Id property. Your Person class does neither.
Also, in my experience, all public methods in entities must be declared virtual (though this may not be required if you eager load everything).
I got around this by manually marking each Entity with an interface.
public class MyAutomappingConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Type type)
{
return type.GetInterfaces().Contains(typeof (IEntity));
}
}
I'm having an issue with Fluent NHibernate AutoPersistenceModelGenerator. It doesn't want to pick up custom maps.
Using Sharp Architecture 2.0, Fluent NHibernate 1.2 and NHibernate 3.1.
My current relevant configuration is as follows:
public AutoPersistenceModel Generate()
{
// This mappings group works with the exception of custom maps!!
var mappings = AutoMap.AssemblyOf<SecurableEntity>(new AutomappingConfiguration());
mappings.Conventions.Setup(GetConventions());
mappings.IgnoreBase<Entity>();
mappings.IgnoreBase<SecurableEntity>();
mappings.IgnoreBase(typeof(EntityWithTypedId<>));
mappings.UseOverridesFromAssemblyOf<AutoPersistenceModelGenerator>();
//mappings.UseOverridesFromAssemblyOf<UserMap>(); // Should call Override method of UserMap, but doesn't appear to...
mappings.Override<User>(new UserMap().Override()); // This hack fixes the issue with calling the Override method of UserMap.
mappings.UseOverridesFromAssemblyOf<UserMap>();
return mappings;
}
class UserMap : IAutoMappingOverride<User>
{
public void Override(AutoMapping<User> mapping)
{
//mapping => mapping.Table("Users");
mapping.Table("Users");
}
public Action<AutoMapping<User>> Override()
{
return map =>
{
map.Table("Users");
};
}
}
I've tried making various modifications to the configuration and pouring over internet articles on Fluent NHibernate, to no avail. I have a working version using Sharp Arch 1.x, and earlier versions of NHibernate and Fluent. I'm assuming that there has been a change in syntax that I'm missing. Any and all help would be greatly appreciated.
Thank you!
John
Fluent NHibernate use Assembly.GetExportedTypes() method to get all the overrides from given assembly. As this method's documentation say, it gets the public types defined in this assembly that are visible outside the assembly. Your override is implicitly internal. Just add public before class UserMap and it'll work.
I am retrofitting a very large application to use NHibernate as it's data access strategy. Everything is going well with AutoMapping. Luckily when the domain layer was built, we used a code generator. The main issue that I am running into now is that every collection is hidden behind a custom class that derives from List<>. For example
public class League
{
public OwnerList owners {get;set;}
}
public class OwnerList : AppList<Owner> { }
public class AppList<T> : List<T> { }
What kind of Convention do I have to write to get this done?
I don't think you're going to be able to achieve this with a convention. You will have to create an auto mapping override and then do the following:
mapping.HasMany(l => a.owners).CollectionType<OwnerList>();
Im making the switch from Fluent Mapping to Automapping in my current project.
If I have the following domain:
public class Matter{
public Client Client{get;set;}
}
public class Client {
public Name Name{get;set;}
}
public class Name{
public string FirstName{get;set;}
public string LastName{get;set;}
}
When Automapping this model, the column names for the Name component are expected to be:
Name_FirstName
Name_LastName
(i already have an underscore convention).
Is there a convention I could implement that would get the automapper to generate column names like:
Client_Name_FirstName
Client_Name_LastName
I hope ive described that effectively.
Cheers,
Byron
Sorry to pick up an old message but for the sake of others coming from a search engine perhaps http://wiki.fluentnhibernate.org/Conventions is what you're after?