Как игнорировать сопоставление свойства с помощью сопоставления по коду «Соглашения» - PullRequest
4 голосов
/ 20 октября 2011

Есть ли способ избежать сопоставления свойства с помощью NHibernate 3.2 с использованием сопоставления в соответствии с соглашениями о коде?По умолчанию все свойства сопоставлены.

Ответы [ 3 ]

2 голосов
/ 21 октября 2011

Насколько я знаю, есть два варианта:

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;
}
2 голосов
/ 22 апреля 2012

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

Условия могут быть перемещены в отдельный метод или класс. Над ней можно сделать оболочку строгого типа, основанную на выражениях.

1 голос
/ 20 октября 2011

Дубликат: Игнорировать столбец, используя отображение по коду в HNibernate

, вы можете использовать следующее:

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