C# 如何使用“按代码映射”忽略属性映射;公约“;
是否有任何方法可以避免使用代码约定映射将属性映射到NHibernate 3.2?默认情况下,将映射所有属性。重复: 您可以使用以下选项:C# 如何使用“按代码映射”忽略属性映射;公约“;,c#,nhibernate,nhibernate-mapping,C#,Nhibernate,Nhibernate Mapping,是否有任何方法可以避免使用代码约定映射将属性映射到NHibernate 3.2?默认情况下,将映射所有属性。重复: 您可以使用以下选项: mapper.IsPersistentProperty((mi, declared) => { if (mi.DeclaringType == typeof (Your
mapper.IsPersistentProperty((mi, declared) =>
{
if (mi.DeclaringType == typeof (YourType) && mi.Name == "PropertyNameToIgnore")
return false;
return true;
});
据我所知,有两种选择: 1) 扩展ConventionModelMapper和SimpleModelInspector以扩展IsPersistentProperty,从而满足您的需要 2) 按如下方式使用IsPersistentProperty:
...
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;
}
。。。
mapper.IsPersistentProperty((memberInfo,声明)=>IsPersistentProperty(mapper.ModelInspector,memberInfo,声明为“YourPropertyName”);
...
公共静态bool IsPersistentProperty(IModeInspector modelInspector、MemberInfo成员、bool声明、字符串propertyName)
{
return(声明的| |(成员为PropertyInfo)和&!IsReadOnlyProperty(成员))&&!member.Name.Equals(propertyName);
}
私有静态bool为只读属性(MemberInfo主题)
{
const BindingFlags defaultBinding=BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
var property=主体为PropertyInfo;
if(属性==null)
{
返回false;
}
if(CanReadCantWriteInsideType(属性)| | CanReadCantWriteInBaseType(属性))
{
return!PropertyToField.DefaultStrategies.Values.Any(s=>subject.DeclaringType.GetField(s.GetFieldName(property.Name),defaultBinding)!=null)| | IsAutoproperty(property);
}
返回false;
}
私有静态bool IsAutoproperty(PropertyInfo属性)
{
返回属性.ReflectedType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
|BindingFlags.DeclaredOnly).Any(pi=>pi.Name==string.Concat(“k_ubackingfield”);
}
私有静态bool CanReadCantWriteInsideType(PropertyInfo属性)
{
return!property.CanWrite&&property.CanRead&&property.DeclaringType==property.ReflectedType;
}
私有静态bool CanReadCantWriteInBaseType(PropertyInfo属性)
{
if(property.DeclaringType==property.ReflectedType)
{
返回false;
}
var rfprop=property.DeclaringType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
|BindingFlags.DeclaredOnly).SingleOrDefault(pi=>pi.Name==property.Name);
返回rfprop!=null&&!rfprop.CanWrite&&rfprop.CanRead;
}
2)作为IsPersistentProperty默认实现的复制和粘贴的替代方案,它可以通过反射重用:
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" ) );
var-mapper=new ConventionModelMapper();
var field=mapper.ModelInspector.GetType()
.GetField(“isPersistentProperty”,BindingFlags.NonPublic | BindingFlags.Instance);
var ispp=(Func)field.GetValue(mapper.ModelInspector);
映射器.IsPersistentProperty((mi,b)=>ispp(mi,b)
&&(/*此处的任何条件*/mi.Name!=“SomeFiledName”);
可以将条件移动到单独的方法或类。基于表达式的stronly类型的包装可以在它上面完成。是。不要绘制地图。i、 e.不要在类映射代码中使用属性(x=>x.MyProperty)。@ThilakNathen我已经更新了这个问题。目前没有简单的方法。请投票支持这样做:您能提供一个最简单的例子,使用BeforeMapProperty处理程序忽略任意数量的属性吗?这是错误的代码。它使每个映射类的每个属性都持久化,但类型类的“PropertyNameToIgnore”除外。这些是只读的,曾经通过字段映射的,等等。你能给出一个如何使用它的示例吗?