Временно отключить идентификационный столбец с помощью Fluent AutoMap? - PullRequest
0 голосов
/ 03 февраля 2012

Я начал тестировать Fluent NHibernate в C #. У меня хорошо нормализованная объектная структура с 20 родственными классами.В настоящее время я использую Fluent 1.3 с NHibernate 3.2.До сих пор мне удавалось использовать функцию AutoMap, которая мне подходит, очень удобно!

НО ... 3 таблицы являются "enum таблицами", для которых необходимо установить записи с определенным значением Id.Я попытался сделать ручные отображения этих таблиц и позволить остальным быть автоматизированными.Но когда создается таблица вручную, происходит сбой, поскольку она ссылается на таблицу, которая была автоматически обработана (и недоступна для ручного преобразователя)?Я пытался создать пользовательское соглашение, но безуспешно.

public class OverrideIdentityGeneration : Attribute
{
}

public class ConventionIdentity : AttributePropertyConvention<OverrideIdentityGeneration>
{
    protected override void Apply(OverrideIdentityGeneration attribute, IPropertyInstance instance)
    {
        instance.Generated.Never();
    }
}

Есть ли другой способ?Было бы грустно быть вынужденным снова использовать ручное отображение для всех классов ....

Ответы [ 2 ]

4 голосов
/ 06 февраля 2012
class MyIdConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        if (instance.EntityType == ...)
        {
            instance.GeneratedBy.Assigned();
        }
    }
}

Обновление:

для классов, подобных enum, часто проще определить enum как id

class ConfigValue
{
    public virtual Config Id { get; set; }
}

// the convention is easy
if (instance.EntityType.IsEnum)
{
    instance.GeneratedBy.Assigned();
    // to save as int and not string
    instance.CustomType(typeof(Config));
}

// querying without magic int values
var configValue = Session.Get<ConfigValue>(Config.UIColor);
0 голосов
/ 07 февраля 2012

Я использовал идею, данную Fifo, и расширил ее, чтобы вместо нее использовать собственный атрибут.Чтобы сделать код читабельным и избежать избыточности при использовании аналогичной идеи в других соглашениях, я добавил метод расширения для проверки пользовательского атрибута.

Это код, с которым я закончил:

/// <summary>
/// Convention to instruct FluentNHIbernate to NOT generate identity columns
/// when custom attribute is set.
/// </summary>
public class ConventionIdentity : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        if(instance.CustomAttributeIsSet<NoIdentity>())
            instance.GeneratedBy.Assigned();
    }
}

/// <summary>
/// Custom attribute definition.
/// </summary>
public class NoIdentity : Attribute
{
}

/// <summary>
/// Example on how to set attribute.
/// </summary>
public class Category
{
    [NoIdentity]
    public int Id { get; set; }
    public string Name { get; set; }
}

public static class IInspectorExtender
{
    /// <summary>
    /// Extender to make convention usage easier.
    /// </summary> 
    public static T GetCustomAttribute<T>(this IInspector instance)
    {
        var memberInfos = instance.EntityType.GetMember(instance.StringIdentifierForModel);
        if(memberInfos.Length > 0)
        {
            var customAttributes = memberInfos[0].GetCustomAttributes(false);
            return customAttributes.OfType<T>().FirstOrDefault();
        }
        return default(T);
    }
}
...