2011-10-20 43 views
4

有没有什么办法可以避免使用映射的代码约定使用NHibernate 3.2映射属性?默认情况下,所有属性都被映射。如何忽略映射的代码使用代码映射“约定”

+0

是的。不要映射它。即不要在您的ClassMapping代码中使用Property(x => x.MyProperty)。 –

+0

@ ThilakNathen我已经更新了这个问题。 – Newbie

+0

目前没有简单的方法。请投票支持,以实现目标:[NH-2816](https://nhibernate.jira.com/browse/NH-2816) –

回答

2

有两个选项,据我所知:

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; 
} 
+1

1)不能使它工作:( –

1

重复:Ignore column using mapping by code in HNibernate

您可以使用以下方法:

mapper.IsPersistentProperty((mi, declared) => 
              { 
               if (mi.DeclaringType == typeof (YourType) && mi.Name == "PropertyNameToIgnore") 
                return false; 
               return true; 
              }); 
+0

您能提供一个最简单的例子,它会导致任何数量的属性被忽略一个BeforeMapProperty处理程序? – Newbie

+0

修改答案 –

+0

这是错误的代码。它使每个映射类的EVERY属性永久保留,除了YourType类的“PropertyNameToIgnore”。这些是只读的,曾经通过字段映射的等等。 –

2

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")); 

条件可以被移动到单独的方法或类。一个基于表达式的强类型包装可以在它上面完成。

+0

你可以给一个示例如何使用它? – Paul