ignoreproperty

246 views
Skip to first unread message

Blee

unread,
Mar 14, 2009, 2:44:39 AM3/14/09
to Fluent NHibernate
I just recently started using Fluent NHibernate and have to say that
it is a fantastic help. Recently we ran into a small issue that I
can't seem to find an obvious way around. Obvious to me, I should
say. :)

We use this class as a base type so that the Id and a couple of other
fields will be persisted to each table. The problem that we're having
is that we would like to ignore one property. We are using
automapping for almost all of our classes and would prefer if there
were a way to ignore the property without having to specifically use:

.ForTypesThatDeriveFrom<SomeClass>(c => c.IgnoreProperty(p =>
p.PropertyName))

for each class.

I appreciate any help you can give. Thank you.

Adam Dymitruk

unread,
Mar 14, 2009, 2:55:58 PM3/14/09
to fluent-n...@googlegroups.com
What would you suggest?
--
Adam Dymitruk
Director of IT
SCANit International (a division of APARA Systems)
mobile: 604.831.7804

Blee

unread,
Mar 14, 2009, 3:45:21 PM3/14/09
to Fluent NHibernate
I was hoping that I was simply missing how to do this. Ideally, what
I would like to be able to ignore a property off of a base class
instead of having to ignore that property on each child class.
Unfortunately, at the moment, I get an invalid cast trying to
AutoMap<BaseClass> to AutoMap<SubClass>. Since we don't get
covariance with generics until .Net 4.0, I'm not quite sure how I
would go about implementing that.

I appreciate any thoughts or ideas on how to do this.
> mobile: 604.831.7804- Hide quoted text -
>
> - Show quoted text -

Jon Kruger

unread,
Mar 14, 2009, 4:26:41 PM3/14/09
to Fluent NHibernate
I haven't tried what I'm about to propose, but I think it would work.

1) Create an attribute that you will put on the properties that you
want to ignore (for example, an [Ignore] attribute)
2) Override the IPropertyConvention (see here:
http://wiki.fluentnhibernate.org/show/Conventions). In the Accept()
method, check the property to see if it has the [Ignore] attribute,
and if it does, return false, otherwise return true.

Hope this works!

Jon

Blee

unread,
Mar 14, 2009, 6:11:09 PM3/14/09
to Fluent NHibernate
Using a property convention, I am able to apply a particular property
convention to that property (rename tables, fields, etc) but I don't
see a way to ignore it. If there is, this approach would be ideal.

James Gregory

unread,
Mar 14, 2009, 7:00:27 PM3/14/09
to fluent-n...@googlegroups.com
Although the idea is sound, it unfortunately won't work as there's no way to ignore properties through conventions. Definitely something we need to implement.

Unfortunately there's no workaround either. I've tried hacking something together, but I've wasted half an hour already with no luck. Sorry.

Jon Kruger

unread,
Mar 14, 2009, 9:27:05 PM3/14/09
to fluent-n...@googlegroups.com
What's the purpose of the Accept() method then if it's not to ignore certain properties?

James Gregory

unread,
Mar 14, 2009, 9:49:06 PM3/14/09
to fluent-n...@googlegroups.com
Automapping is a different game entirely. The Accept method is used to ignore properties when applying conventions. The automapper has an explicit IgnoreProperty that's used to actually not map the property at all, which is completely different.

Blee

unread,
Mar 15, 2009, 2:21:42 AM3/15/09
to Fluent NHibernate
That is pretty much what I assumed. I appreciate the feedback. If I
think of another solution to this issue, I'll let ya'll know.

gre...@slavec.net

unread,
Mar 16, 2009, 3:44:40 AM3/16/09
to Fluent NHibernate
You can try this:

...
.WithConvention(convention =>
{

convention.ForAttribute<UnmappableAttribute>
(UnmappableAttribute.RemoveMapping);
})


...

public class UnmappableAttribute : Attribute
{
public static void RemoveMapping(UnmappableAttribute
attribute, IProperty property)
{
property.AddAlteration(_RemoveMapping);
}

private static void _RemoveMapping(XmlElement element)
{
if (element == null)
return;

if (element.ParentNode == null)
return;

element.ParentNode.RemoveChild(element);
}
}

Blee

unread,
Mar 16, 2009, 10:11:25 AM3/16/09
to Fluent NHibernate
That worked brilliantly. Thank you.

Jon Kruger

unread,
Mar 17, 2009, 3:15:01 PM3/17/09
to Fluent NHibernate
That doesn't work with the new convention overhaul (the methods are
all changed). I was able to do it like this:

public class CustomClassConvention : IClassConvention
{
public bool Accept(IClassMap target)
{
return true;
}

public void Apply(IClassMap target)
{
var propertiesToIgnore = target.Parts.OfType<IProperty>()
.Where(p => p.Property.GetCustomAttributes(typeof
(AutoMapIgnoreAttribute), true).Length > 0).ToList();
foreach (var property in propertiesToIgnore)
((IList<IMappingPart>) target.Parts).Remove(property);

if (target.EntityType.GetCustomAttributes(typeof
(ReadOnlyAttribute), true).Length > 0)
target.ReadOnly();
}
}

public class AutoMapIgnoreAttribute : Attribute
{
}

You'll see some stuff in here that looks like a hack because it is a
hack. :) What would make this easier to do is if we had a RemovePart
() method on the ClasslikeMapBase class, then I wouldn't have to cast
an IEnumerable<T> to an IList<T>. :)

Patch for said change is here: http://jonkruger.com/ClasslikeMapBase.RemovePart.patch

Jon

gre...@slavec.net

unread,
Mar 17, 2009, 3:51:14 PM3/17/09
to Fluent NHibernate
The modification to new conventions is trivial. Check

http://wiki.fluentnhibernate.org/show/ConvertingToNewStyleConventions

It then goes something like this:

public class UnmappableAttributeConvention :
AttributePropertyConvention<UnmappableAttribute>
{
public override void Apply(UnmappableAttributeattribute, IProperty
property)
{
property.AddAlteration(_RemoveMapping);
}
private static void _RemoveMapping(XmlElement element)
{
if (element == null)
return;

if (element.ParentNode == null)
return;

element.ParentNode.RemoveChild(element);
}

}

and

.ConventionDiscovery.Add< UnmappableAttributeConvention >();

Jon Kruger

unread,
Mar 17, 2009, 3:53:05 PM3/17/09
to fluent-n...@googlegroups.com
I didn't realize you could do it that way... awesome.
Reply all
Reply to author
Forward
0 new messages