Как вы сопоставляете перечисление как значение int с fluent NHibernate?



вопрос говорит, что все это действительно, по умолчанию он отображается как string но мне нужно, чтобы он отображался как int.



В настоящее время я использую PersistenceModel для установки моих конвенций, если это имеет какое-либо значение. Спасибо заранее.



обновление
Обнаружил, что попадание на последнюю версию кода из багажника разрешило мои беды.

689   7  

7 ответов:

способ определения этого соглашения иногда менялся раньше, теперь:

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum);
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}

Итак, как уже упоминалось, получение последней версии Fluent NHibernate из багажника привело меня туда, где мне нужно было быть. Пример сопоставления для перечисления с последним кодом:

Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));

пользовательский тип заставляет его обрабатываться как экземпляр перечисления, а не использовать GenericEnumMapper<TEnum>.

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


это выскочило на моей недавней деятельности, и все изменилось в новых версиях Fluent NHibernate, чтобы сделать это проще.

чтобы все перечисления отображались как целые числа, теперь вы можете создать соглашение следующим образом:

public class EnumConvention : IUserTypeConvention
{
    public bool Accept(IProperty target)
    {
        return target.PropertyType.IsEnum;
    }

    public void Apply(IProperty target)
    {
        target.CustomTypeIs(target.PropertyType);
    }

    public bool Accept(Type type)
    {
        return type.IsEnum;
    }
}

тогда ваше отображение должно быть только:

Map(quote => quote.Status);

вы добавляете соглашение к своему свободному отображению NHibernate вот так;

Fluently.Configure(nHibConfig)
    .Mappings(mappingConfiguration =>
    {
        mappingConfiguration.FluentMappings
            .ConventionDiscovery.AddFromAssemblyOf<EnumConvention>();
    })
    ./* other configuration */

Не забывайте о перечислениях значение null (например,ExampleEnum? ExampleProperty)! Их нужно проверять отдельно. Вот как это делается с новой конфигурацией стиля FNH:

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum ||
            (x.Property.PropertyType.IsGenericType && 
             x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) &&
             x.Property.PropertyType.GetGenericArguments()[0].IsEnum)
            );
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}

вот как я сопоставил свойство enum со значением int:

Map(x => x.Status).CustomType(typeof(Int32));

работает для меня!

для тех, кто использует Fluent NHibernate с Automapping (и потенциально контейнер IoC):

The IUserTypeConvention - это как @Жюльенответ выше:https://stackoverflow.com/a/1706462/878612

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum);
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}

конфигурация Fluent NHibernate Automapping может быть настроена следующим образом:

    protected virtual ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
            .Database(SetupDatabase)
            .Mappings(mappingConfiguration =>
                {
                    mappingConfiguration.AutoMappings
                        .Add(CreateAutomappings);
                }
            ).BuildSessionFactory();
    }

    protected virtual IPersistenceConfigurer SetupDatabase()
    {
        return MsSqlConfiguration.MsSql2008.UseOuterJoin()
        .ConnectionString(x => 
             x.FromConnectionStringWithKey("AppDatabase")) // In Web.config
        .ShowSql();
    }

    protected static AutoPersistenceModel CreateAutomappings()
    {
        return AutoMap.AssemblyOf<ClassInAnAssemblyToBeMapped>(
            new EntityAutomapConfiguration())
            .Conventions.Setup(c =>
                {
                    // Other IUserTypeConvention classes here
                    c.Add<EnumConvention>();
                });
    }

*тогда CreateSessionFactory смогите быть использовано в IoC как замок Виндзор (используя PersistenceFacility и установщик) легко. *

    Kernel.Register(
        Component.For<ISessionFactory>()
            .UsingFactoryMethod(() => CreateSessionFactory()),
            Component.For<ISession>()
            .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
            .LifestylePerWebRequest() 
    );

вы можете создать NHibernate IUserType, и укажите его с помощью CustomTypeIs<T>() на карте недвижимости.

вы должны сохранить значения как int / tinyint в вашей таблице БД. Для сопоставления вашего перечисления вам нужно правильно указать сопоставление. Пожалуйста, смотрите ниже отображение и перечисление образца,

Сопоставление Класс

public class TransactionMap : ClassMap Transaction
{
    public TransactionMap()
    {
        //Other mappings
        .....
        //Mapping for enum
        Map(x => x.Status, "Status").CustomType();

        Table("Transaction");
    }
}

перечисление

public enum TransactionStatus
{
   Waiting = 1,
   Processed = 2,
   RolledBack = 3,
   Blocked = 4,
   Refunded = 5,
   AlreadyProcessed = 6,
}

Comments

    Ничего не найдено.