How to map Tsql User Defined Function using Fluent NHibernate? - sql

How to map Tsql User Defined Function using Fluent NHibernate? I have found a solution which works with hbm.
http://ayende.com/blog/1720/using-sql-functions-in-nhibernate
But I am using ClassMaps.

I believe that <sql-query> is not yet implemented in FluentNHibernate. There's an open issue on GitHub.
However, you can mix both fluent mappings and .hbm mappings using FluentNHibernate configuration. Here's an example for that: http://www.dotnetguy.co.uk/post/2009/11/01/stored-procedures-with-fluent-nhibernate/
Something like this:
Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.Is("...")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionFactory>())
.Mappings(m => m.HbmMappings.AddFromAssemblyOf<SessionFactory>())
.BuildSessionFactory();

Related

Fluent NHibernate - How do I create a one to many mapping which has a bridge table in the middle?

How do I create a one to many mapping which has a bridge table in the middle?
I basically have 3 tables: Items, Tags, and TagsToItems.
Each Item can have many Tags as defined by the TagsToItems table. How do I set up this mapping correctly using Fluent NHibernate?
I've been playing with HasMany but haven't quite figured out how this works with a bridge table.
HasMany(x => x.Tags).Table("TagsToItems").KeyColumn("ItemId");
My latest attempt to solve this problem looks like this:
HasManyToMany(x => x.Tags)
.AsBag()
.Table("TagsToItems")
.ParentKeyColumn("ItemId")
.ChildKeyColumn("TagId")
.Cascade.All()
.Inverse();
However this is throwing the error:
Initializing[Namespace.Item#11]-failed to lazily initialize a
collection of role:
Namespace.DataAccess.NHibernate.Entities.Item.Tags, no session or
session was closed
It turns out that the problem is with using the Tags collection associated to an Item.
The Tags collection could not be lazily initialised because by the time I was trying to use it (in my view) the session scope of the NHibernate session had closed.
I solved this by setting .Not.LazyLoad() on the mapping:
HasManyToMany(x => x.Tags)
.AsBag()
.Table("TagsToItems")
.ParentKeyColumn("ItemId")
.ChildKeyColumn("TagId")
.Not.LazyLoad()
.Cascade.All();

NHibernate 3.2 conform composite id

I am upgrading to NHibernate 3.2. I was using Fluent NHibernate but I don't see a new build for NH 3.2. I am looking at using the included Conform mapper but it does not appear to allow for a composite id. I can't change the database so I have a constraint.
In Fluent NHibernate I had this (names changed for example only):
Schema("MY_SCHEMA");
Table("MY_TABLE");
CompositeId()
.KeyProperty(x => x.CompanyId, "COMPANY_ID")
.KeyProperty(x => x.OrderId, "ORDER_ID")
.KeyProperty(x => x.OrderDate, "ORDER_DATE")
.KeyProperty(x => x.ProgramId, "PROGRAM_ID");
How would I do this with Conform in NH 3.2?
Thanks,
Paul
You can try with:
mapper.Class<YourEntity>(m=>{
m.Table("MY_TABLE");
m.Schema("MY_SCHEMA");
m.ComposedId(cid=>
{
cid.Property((e)=>e.CompanyId);
cid.Property((e)=>e.OrderId);
cid.Property((e)=>e.OrderDate);
//others...
});
});
And, I'm just guessing since I can't figura out your db, you would probably map the single portion of the key a many-to-one ( ie the old key-many-to-one you would write in hbm ), in order to do so, use cid.ManyToOne() instead of cid.Property(..);

Fluent NHibernate - HasMany().WithKeyColumnName

I just got the latest version of Fluent from Google code and it seems some of the mapping has changed since I last used it.
Previously I could Map a relationship using the following when the id I was joining on had a different name in the second table
HasMany(x => x.Roles).WithTableName("tbl_Roles").WithKeyColumn("RoleId");
How is done in the latest release of Fluent?
Thanks
HasMany(x => x.Roles)
.WithTableName("tbl_Roles")
.KeyColumns.Add("RoleId");
Multiple column support was added, so the method signature needed to be improved to make it clear what's happening.
This works for me:
HasMany(x => x.Roles)
.WithTableName("tbl_Roles")
.KeyColumnNames.Add("RoleId");

FluentNHibernate HasMany not filling collection

I have a one to many relationship with the following config
HasMany(x => x.Staff)
.Inverse()
.Cascade.All();
But I get a collection failed to initialize error.
Dont I have to specify the foreignkey here, examples I found do not????
How does it know which is the foreign key?
EDIT: Looking closer at the exception the sql is trying to use field Staff_id
when I have said it is StaffID??
Malcolm
Try
HasMany(x => x.Staff)
.KeyColumnNames.Add("StaffID")
.Inverse()
.Cascade.All();
Staff_id is the auto configure default, although you can set what conventions auto-configure uses.
If you're mapping the collection to an IList<T>, you'll want to add AsBag() or NHibernate will complain about a missing "idx" column. If you want to lazy load the collection add .LazyLoad(). And I usually go with .Cascade.AllDeleteOrphan().

How do you map an enum as string in fluent nhibernate?

Is it possible to map an enum as a string using Fluent Nhibernate?
Yes, it does that by default if you just do:
Map(x => x.YourProperty);
Make sure you're using the latest version off the trunk.
As Yavor Shahpasov pointed out in the comments, in more recent versions you can accomplish the same with:
Map(x => x.Property).CustomType<GenericEnumMapper<YourPropertyEnumType>>();
and there is also the EnumString class you can pass as customType