Is there any way to avoid a property from being mapped with NHibernate 3.2 using mapping by code conventions? By default, all properties are mapped.
Asked
Active
Viewed 2,314 times
5
-
Yes. Don't map it. i.e. don't go Property(x => x.MyProperty) in your ClassMapping code. – Thilak Nathen Oct 20 '11 at 01:22
-
There is currently no easy way of doing it. Please vote for this to make it happen: [NH-2816](https://nhibernate.jira.com/browse/NH-2816) – Michael Logutov Jun 17 '13 at 11:44
3 Answers
3
2) As alternative to copy&paste of default implementation of IsPersistentProperty it can be reused via reflection:
var mapper = new ConventionModelMapper();
var field = mapper.ModelInspector.GetType()
.GetField( "isPersistentProperty", BindingFlags.NonPublic | BindingFlags.Instance );
var ispp = (Func<MemberInfo, bool, bool>)field.GetValue( mapper.ModelInspector );
mapper.IsPersistentProperty( ( mi, b ) => ispp( mi, b )
&& ( /*any conditions here*/ mi.Name != "SomeFiledName" ) );
Conditions can be moved to separate method or class. An stronly-typed wrapper based on expressions can be done above it.

Vasiliy Shiryaev
- 600
- 4
- 12
2
There are two options as far as I know:
1)Extend ConventionModelMapper and SimpleModelInspector to extend IsPersistentProperty such that it meets your need.
2)Use IsPersistentProperty as follows:
...
mapper.IsPersistentProperty((memberInfo, declared) => IsPersistentProperty(mapper.ModelInspector, memberInfo, declared, "YourPropertyName"));
...
public static bool IsPersistentProperty(IModelInspector modelInspector, MemberInfo member, bool declared, string propertyName)
{
return (declared ||(member is PropertyInfo) && !IsReadOnlyProperty(member)) && !member.Name.Equals(propertyName);
}
private static bool IsReadOnlyProperty(MemberInfo subject)
{
const BindingFlags defaultBinding = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
var property = subject as PropertyInfo;
if (property == null)
{
return false;
}
if (CanReadCantWriteInsideType(property) || CanReadCantWriteInBaseType(property))
{
return !PropertyToField.DefaultStrategies.Values.Any(s => subject.DeclaringType.GetField(s.GetFieldName(property.Name), defaultBinding) != null) || IsAutoproperty(property);
}
return false;
}
private static bool IsAutoproperty(PropertyInfo property)
{
return property.ReflectedType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
| BindingFlags.DeclaredOnly).Any(pi => pi.Name == string.Concat("<", property.Name, ">k__BackingField"));
}
private static bool CanReadCantWriteInsideType(PropertyInfo property)
{
return !property.CanWrite && property.CanRead && property.DeclaringType == property.ReflectedType;
}
private static bool CanReadCantWriteInBaseType(PropertyInfo property)
{
if (property.DeclaringType == property.ReflectedType)
{
return false;
}
var rfprop = property.DeclaringType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
| BindingFlags.DeclaredOnly).SingleOrDefault(pi => pi.Name == property.Name);
return rfprop != null && !rfprop.CanWrite && rfprop.CanRead;
}

Newbie
- 7,031
- 9
- 60
- 85
1
Duplicate: Ignore column using mapping by code in HNibernate
you can use the following:
mapper.IsPersistentProperty((mi, declared) =>
{
if (mi.DeclaringType == typeof (YourType) && mi.Name == "PropertyNameToIgnore")
return false;
return true;
});

Community
- 1
- 1

Mohamed Abed
- 5,025
- 22
- 31
-
Can you provide the simplest possible example that will cause any number of properties to be ignored using a BeforeMapProperty handler? – Newbie Oct 20 '11 at 15:19
-
This is wrong code. It makes EVERY property of every mapped class persistent except "PropertyNameToIgnore" of YourType class. Those are readonly, the once mapped via fields and so on. – Vasiliy Shiryaev Jun 16 '13 at 17:04