Fluent Nhibernate - Schema Mapping Question - nhibernate

If in my classmap I have
SchemaAction.None();
and if I also have
.ExposeConfiguration(cfg =>
{
new SchemaExport(cfg)
.Create(false, false);
})
Can I ensure that nhib will not touch the db schema in any fashion.
In other words the only write action will be that of entities to the tables?

The better way would be to just leave out the ExposeConfiguration call altogether.
Fluently.Configure()
.Database(....)
.Mappings(....)
.BuildSessionFactory();

Related

How to set default-cascade in Fluent NHibernate

I find we can specify the "default-cascade" attribute of the element. But how can I do it in Fluent NHibernate? And I don't want to use AutoMapping.
The detailed description could be found here: https://github.com/jagregory/fluent-nhibernate/wiki/Conventions. An extract:
There are some situations that are so obvious that they just cried out for a simple shortcut that can be applied globally to your project:
Table.Is(x => x.EntityType.Name + "Table")
...
DefaultCascade.All()
...
And this way we can use it:
Fluently.Configure()
.Database(/* database config */)
.Mappings(m =>
{
m.FluentMappings
.AddFromAssemblyOf<Entity>()
.Conventions.Add(DefaultCascade.All());
})
Also check this, to get some idea how to implement own Conventions Fluent NHibernate automapping and cascading

Fluent NHibernate: Mixing Automapping and manual mapping

If using Fluent NHibernate, is it possible to automap most classes, but specify that a couple of particular classes should be mapped using the regular fluent API rather than being automapped? And if so, can anyone point me to some sample code that shows how to do it?
Thanks!
It is possible and easy to mix-up mapping configurations:
var cfg = Fluently.Configure()
.Database(configurer)
.Mappings(map =>
{
// Automapping
map.AutoMappings.Add(AutoMap.Assemblies(Assembly.GetExecutingAssembly())
.Where(type => type == typeof(Domain.Market.Share))
.Where(type => type == typeof(Domain.HR.Employee)));
// Fluent mappings
map.FluentMappings.AddFromAssemblyOf<Domain.Client.Macys>();
});
Good luck. ;-)

Fluent mapping - entities and classmaps in different assemblies

When using fluent configuration to specify fluent mappings like this:
.Mappings(m => m.FluentMappings.AddFromAssembly(typeof(UserMapping).Assembly))
At the moment I am getting a "NHibernate.MappingException : No persister for" error.
Is it a problem that my Entities and my ClassMaps are in different assemblies? Presumably AddFromAssembly is interested in the assembly that holds the class maps, not the entities? (that is what I have assumed)
Thanks!
UPDATE:
Sorry for not responding to answers very quickly - I had to travel unexpectedly after setting the bounty.
Anyway, thanks for the responses. I've taken a look through them and have updated my code to use AddFromAssemblyOf rather than AddFromAssembly, but still am getting the same error. Possibly I am doing something stupid. Here is the full code for the session factory code I am using:
public class NHibernateHelper
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var mysqlConfig = FluentNHibernate.Cfg.Db.MySQLConfiguration
.Standard
.ConnectionString("CONNECTION STRING OMITTED")
.UseOuterJoin()
.ProxyFactoryFactory("NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
_sessionFactory = FluentNHibernate.Cfg.Fluently.Configure()
.Database(mysqlConfig)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<User>())
.BuildSessionFactory();
}
return _sessionFactory;
}
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
I receive this exception when trying to run a test in nunit that makes use of a repository using this session mechanism:
NHibernate.MappingException : No persister for: xxxx.Model.Entities.User
Thanks
P.S.:
I've tried using both and in AddFromAssemblyOf();
Project with mapping definitions (DataAccess) has reference to project with entities (Model).
What version of Fluent NHibernate are you using? There have been problems with the release candidate and the 1.0 release versions. You may want to consider downloading the latest version from the SVN repository.
http://fluent-nhibernate.googlecode.com/svn/trunk/
Additionally, you may want to check the connection string to make sure that it is completely correct, and you want to make sure that "User" below points to a class.
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<User>())
Also, I should mention that when you use AddFromAssemblyOf, fluent will try to map EVERY class in that assembly. If you have any other classes in that namespace you will want to filter them. There are several different ways to accomplish this. The simplest way is to just place all of the POCOs you want to map in their own namespace and then do something like the following.
.Mappings(m => m.AutoMappings
.Add(AutoMap.AssemblyOf<MyNamespace.Entities.MyClass>()
.Where(type => type.Namespace == "MyNamespace.Entities")
The Where clause will filter items you don't want mapped.
Is it a problem that my Entities and my ClassMaps are in different assemblies?
No there is nothing wrong with that as long as you ClassMap project have refrerence to your Entities project
anyway try this :
m.FluentMappings.AddFromAssemblyOf<UserMapping>()
if this doesn't work post the entire error
Certainly having your entities in a different assembly should not cause a problem as Yassir alludes to above.
According to the Fluent NHibernate Wiki the AddFromAssemblyOf method infers or reflects on the Assembly that contains all of your entities and will map to them when you supply any entity name to it. From the documentation on the FNH wiki you would construct the method as follows:
m.FluentMappings
.AddFromAssemblyOf<YourEntity>();
Therefore in your example, if the entity you are mapping is named User then your code should be constructed as follows:
m.FluentMappings
.AddFromAssemblyOf<User>();
Hope this is of help.
has this been solved? if not could you inlcude your setup?
for example here is my example one
public static ISessionFactory GetSessionFactory()
{
//Old way, uses HBM files only
//return (new Configuration()).Configure().BuildSessionFactory(); //requies the XMl file.
//get database settings.
Configuration cfg = new Configuration();//.Configure();
ft = Fluently.Configure(cfg);
//DbConnection by fluent
ft.Database
(
MsSqlConfiguration
.MsSql2005
.ConnectionString(c => c
.Server(".\\SqlExpress")
.Database("NhibTest")
.TrustedConnection()
)
.ShowSql()
.UseReflectionOptimizer()
);
//set up the proxy engine
//cfg.Properties.Add("proxyfactory.factory_class", "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
//get mapping files.
ft.Mappings(m =>
{
//set up the mapping locations
m.FluentMappings.AddFromAssemblyOf<PersonMap>();//.ExportTo("C:\\mappingfiles");
//m.Apply(cfg);
});
//return the SessionFactory
return ft.BuildSessionFactory();
}
the project structure is as follows
project.Data <- mapping files, and Dao's (also hibernate session manager, containing the above code)
project.Core <- POCO's
project.UI
also have look here incase you have a mixture of Fluent NHibernate and NHibernate configuration
Finally have a look at S#arp Architectures way, as i think it includes this mixture
NhibernateSession <- function : private static ISessionFactory CreateSessionFactoryFor
Hope this helps

Set up caching on entities and relationships in Fluent Nhibernate?

Does anyone have an example how to set up and what entities to cache in fluent nhibernate. Both using fluent mapping and auto mapping?
And the same for entity relationships, both one-to-many and many-to-many?
I have been working a a similar situation, where I just want to cache specific elements, and want these elements to be loaded once on start up, and kept in cache, until the application is shut down. This is a read only cache, and is used to populate a list of countries, so that a user can select their country from the list.
I used fluentNhibernate Mappings, and defined Country my class with Cache.readonly()
public class CountryMap : ClassMap<Country> {
public CountryMap() {
Schema("Dropdowns");
Cache.ReadOnly();
// Class mappings underneath
}
}
My user class map looks like this:
public class UserMap : ClassMap<User> {
Id(x => x.Id).Column("UserId");
Map(x => x.FirstName);
Map(x => x.LastName);
References(x => x.Country)
.Column("CountryId");
}
I manually configure Fluent Nhibernate to use Second level cache. So in my fluent Confuguration I have:
var sessionFactory = Fluently.Configure()
.Database (...) // set up db here
.Mappings(...) //set up mapping here
.ExposeConfiguration(c => {
// People advice not to use NHibernate.Cache.HashtableCacheProvider for production
c.SetProperty("cache.provider_class", "NHibernate.Cache.HashtableCacheProvider");
c.SetProperty("cache.use_second_level_cache", "true");
c.SetProperty("cache.use_query_cache", "true");
})
.BuildSessionFactory();
I have checked in SQL profiler, and when I get a list of countrys for a user, the are loaded once, and I get cache hits after every other request. The nice thing is that when displaying the users country name, it loads from the cache, and does not make a request to the database. I got some tips from this posting by Gabriel Schenker. Hope that helps? If you found a better/proper way, please let me know? Thanks!

How to set a configuration property when using fluent nhibernate?

In particular, I'd like to set current_session_context_class. I know how to do it in hibernate.cfg.xml, but is it possible at all with pure fluent configuration?
You can use the method ExposeConfiguration on a FluentConfiguration instance, to access the original NHibernate Configuration object.
Then, you'll have access to the Properties property, and you will be able to add the current_session_context_class one.
Here is a the pseudo-code:
Fluently.Configure()
.Database(SQLiteConfiguration.Standard.InMemory)
.ExposeConfiguration(c =>
{
c.Properties.Add("current_session_context_class",
typeof(YourType).FullName);
})
//.AddMapping, etc.
.BuildSessionFactory();