Why is fluent Fluent adding _Id at the end of my columns in the mappings?

10 views
Skip to first unread message

Jim Tanner

unread,
Aug 17, 2009, 12:01:35 PM8/17/09
to Fluent NHibernate
I have the following class

public Car
{
int Id {get;set}
String Color {get;set}
CarType IdCarType {get;set}
}

I am using autoconfiguration and i get the following mapping

<id name="Id" type="Int">
<column name="Id" />
<generator class="identity" />
</id>
<property name="Color" type="String">
<column name="Color" />

<many-to-one name="IdCarType">
<column name="IdCarType_id" />
</many-to-one>

The problem being 'IdCarType_id', my column is actually IdCarType.

Dru Sellers

unread,
Aug 17, 2009, 1:26:10 PM8/17/09
to fluent-n...@googlegroups.com
Its a convention you can override.

-d

James Gregory

unread,
Aug 17, 2009, 1:28:40 PM8/17/09
to fluent-n...@googlegroups.com
By convention your property should be CarType, not IdCarType. If your column is IdCarType then you need to specify that manually by using Column, if this is a domain-wide convention then you should look into defining an actual convention.

Jim Tanner

unread,
Aug 17, 2009, 3:19:35 PM8/17/09
to Fluent NHibernate
Ok i found the documentation and tried to implement
IReferenceConvention. Is it what i need for many to one collections ?
Basically i want :
if my field is a mapped object and starts with id, make it a many to
one.

i found two ways to do it.

public class ManyToOneConventionCorrection
: IReferenceConvention
{
public bool Accept(IManyToOneInstance instance)
{
return instance.Name.ToLower().StartsWith("id");
}

public void Apply(IManyToOneInstance instance)
{
if (Accept(instance))
instance.Column = instance.Name;
}
}

void ApplyConventions(AutoPersistanceModel model)
{
model.Conventions.Setup(s =>s.Add<ManyToOneConventionCorrection>
())
}

It does not work, i never reach any of the code through debugger.
Works well for properties IPropertyConvention and class
IClassConvention, but not for IReference, at least not if reference is
a many to one.


i found this other way to define the convention which works well
2 .
void ApplyConventions(AutoPersistanceModel model)
{
var manyToOneConventionCorrection = ConventionBuilder.Reference.When(
x => x.Expect(y => y.Name.StartsWith("id")),
z => z.Column(z.Name));

autoPersistanceModel.Conventions.Setup(s =>s.Add
(manyToOneConventionCorrection))
}


On 17 août, 19:28, James Gregory <jagregory....@gmail.com> wrote:
> By convention your property should be CarType, not IdCarType. If your column
> is IdCarType then you need to specify that manually by using Column, if this
> is a domain-wide convention then you should look into defining an actual
> convention <http://wiki.fluentnhibernate.org/Conventions>.

James Gregory

unread,
Aug 17, 2009, 3:23:26 PM8/17/09
to fluent-n...@googlegroups.com
You don't need to call Accept, FNH does that.

Your Accept method is wrong. Where did you find that sample? This behaviour changed as part of the release, Accept methods are now not required by default, and you need to explicitly specify them if you want to use them. You can read about it under conditional applying of conventions.

Jim Tanner

unread,
Aug 17, 2009, 4:13:00 PM8/17/09
to Fluent NHibernate
I corrected my code like this and now works fine.

public class ManyToOneConventionCorrection
: IReferenceConvention, IConventionAcceptance<IManyToOneInspector>
{
public void Accept(IAcceptanceCriteria<IManyToOneInspector>
criteria)
{
criteria.Expect(x => x.Name.ToLower().StartsWith("id"));
}

void IConvention<IManyToOneInspector, IManyToOneInstance>.Apply
(IManyToOneInstance instance)
{
instance.Column(instance.Name);
}
}

Note : I wrote the code walking the wiki and taking advantage of the
fluency.
The problem originated of the wiki samples being targeted at a more
recent API than the one of the dll i was using.
Ie Accept method was mandatory and returning bool and now is optionnal
and returns void.
I don't know how much work it would take but it might be good idea if
could release you release some documentation along with each major dll
version.
For instance a chm or html API doc and a snapshot of the wiki along
with the dll.



On 17 août, 21:23, James Gregory <jagregory....@gmail.com> wrote:
> You don't need to call Accept, FNH does that.
> Your Accept method is wrong. Where did you find that sample? This behaviour
> changed as part of the release, Accept methods are now not required by
> default, and you need to explicitly specify them if you want to use them.
> You can read about it under conditional applying of
> conventions<http://wiki.fluentnhibernate.org/Conventions#Conditional_applying_of_...>
> .

Beefy

unread,
Aug 20, 2009, 4:46:09 PM8/20/09
to Fluent NHibernate
Out of curiosity, what would the difference between this
implementation and one using the ForeignKeyConvention be?

using System;
using System.Reflection;
using FluentNHibernate.Conventions;

namespace SAAM.Library.Conventions
{
/// <summary>
/// NHibernate Convention Override for Foreign Key Column Names.
/// </summary>
public class CustomForeignKeyConvention : ForeignKeyConvention
{
/// <summary>
/// Gets the name of the key.
/// </summary>
/// <param name="property">The property.</param>
/// <param name="type">The type.</param>
/// <returns>Name to use for Foreign Key.</returns>
protected override string GetKeyName(PropertyInfo property,
Type type)
{
if (property == null)
return type.Name + "Id";

return property.Name + "Id";
}
}
}

/Michael
Reply all
Reply to author
Forward
0 new messages