2011-10-20 63 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