If I have a collection mapped in Fluent NHibernate and I want to apply an order to that collection how do I do that?
Eg:
HasMany(x => x.PastDates)
.AsBag().Cascade
.SaveUpdate()
.KeyColumnNames.Add("EventId")
.Where(e => e.DateFrom < DateTime.Now.Date)
.Inverse();
I'm looking for the equivalent of the order-by attribute in HBM files.
Thanks
Fluent NHibernate now has an OrderBy method which you can use:
HasMany(x => x.PastDates)
.AsBag().Cascade
.SaveUpdate()
.KeyColumnNames.Add("EventId")
.Where(e => e.DateFrom < DateTime.Now.Date)
.Inverse()
.OrderBy("ColumnName DESC");
It appears that the "order-by" attribute is not in the FluentNHibernate API. I don't see an issue for it so this may be a conscious omission. You should be able to add it using SetAttribute but this user was unable to get it to work.
HasMany(x => x.PastDates)
.AsBag().Cascade
.SaveUpdate()
.KeyColumnNames.Add("EventId")
.Where(e => e.DateFrom < DateTime.Now.Date)
.Inverse()
.SetAttribute("order-by", "column_name");
Be aware that setting order-by may change the collection type that NHibernate uses; however this does not apply for bags.
Related
I have simple task. I need map reference to properity and their ID to other properity.
If I use this map I get error:
"Additional information: Invalid index 24 for this
SqlParameterCollection with Count=24."
public CityMap()
{
Map(x => x.Name).Not.Nullable();
//Map(x => x.AddressID); //This line makes trouble
References(x => x.Address);
We can do it for read operation (I am quite happy to use this approach). Just, one of these properties must be insert="false" and update="false".
In fluent it should be like this:
...
Map(x => x.AddressID)
.Insert(false).Udpate(false)
// or just
// .ReadOnly()
;
References(x => x.Address);
We just have to decide which will be the readonly. Reference? or ValueType? I would make Reference editable, because then all NHibernate built in features will work (e.g. assign to transient object will properly later insert the just created ID)
Also check these for some more details check this or here.
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
I have a Custom Type on Fluent NHibernate and I need to map it to a collection of its type, using HasMany association. However, Fluent Nhibernate doesn't let me indicate on HasMany that its about a custom type like I do in my regular types.
This is my code:
HasMany(x => x.AvailablePaymentOptions)
.KeyColumn("OFFER_ID")
.Cascade.None()
.KeyNullable()
.Not.LazyLoad();
Any thoughts?
Thanks
Finish not using the custom type, but instead, mapping a component:
HasMany(x => x.AvailablePaymentOptions)
.Table("MY_TABLE")
.KeyColumn("MY_COLUMN")
.Component(component =>
{
//MAP YOUR CUSTOM TYPE HERE
})
.Cascade.None()
.KeyNullable()
.Not.LazyLoad();
I have an entity mapping quite similar to this one.
public class MyClassMap : ClassMap<MyClass>
{
public MyClassMap()
{
Id(x => x.Id);
Map(x => x.Code);
Map(x => x.Name);
Map(x => x.Description);
}
}
I'd like to know if there's any possible way to have the Code field (which is not part of the Primary Key) autogenerated by a sequence. There's a GeneratedBy property, but it's only an IdentityPart class member.
I don't see how using Listeners makes it any easier to use a built-in method for using sequence generators for non-ID columns.
However, if the only solution is to hook into OnPreInsert, making a direct query to the DB & invoke the sequence and get its value, then I suppose I'll have to live with it.
Is this how you solved the issue, Mauro?
Edit:
posted the question on the nHibernate & FluentNHibernate google groups:
https://groups.google.com/group/nhusers/browse_thread/thread/35d37b9abf3566f0
https://groups.google.com/group/fluent-nhibernate/browse_thread/thread/35d37b9abf3566f0
You need to use SaveOrUpdateEventListeners. See here to see Jake's reply for how to get it working for Fluent.
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!