Akıcı NHibernate ile bir numaralandırmayı int değeri olarak nasıl eşlersiniz?


88

Soru gerçekten her şeyi söylüyor, varsayılan olarak stringeşlemesi bir int.

Şu anda PersistenceModelherhangi bir fark yaratıyorsa, kurallarımı ayarlamak için kullanıyorum . Şimdiden teşekkürler.

Güncelleme Bagajdan kodun en son sürümüne geçmenin sıkıntılarımı çözdüğünü öğrendim.


5
Sorunu kendiniz çözdüyseniz, cevaplamalısınız, sonra doğru cevap olarak işaretlemelisiniz, böylece gelecekteki araştırmacılar onu bulacaktır.
Jeff Martin

Cevabı lütfen gönderebilir misin?
mxmissile

Bitti çocuklar. Gecikme için üzgünüm. Sadece kütüphanelerin en son sürümüne ihtiyacım olduğu için daha çok sorgusuz sualsiz bir soruyla ne yapmam gerektiğinden emin değildim.
Garry Shutler

2
Google botları için yiyecek: Bunu numaralandırma eşlemem için uygulamadan önce "yükleme koleksiyonuna yasa dışı erişim" elde ediyordum.
4imble

Yanıtlar:


84

Bu kuralı tanımlamanın yolu bazen değişti, şimdi:

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

4
Akıcı nhibernate'in en son versiyonu için doğru cevap bu
Sean Chambers

1
Bu, tüm enum türleri için iyi çalışıyor gibi görünüyor, ancak ya bazılarını dizge ve bazılarını da ints olarak istiyorsanız? Bunun mülk eşleme düzeyinde yapılandırılabilir olması gerektiğini düşünüyorum.
UpTheCreek

4
Null yapılabilir numaralandırmalara izin vermek için bunu genişleten aşağıdaki @SztupY yanıtına bakın. stackoverflow.com/questions/439003/…
Jon Adams

45

Bu yüzden, belirtildiği gibi, Fluent NHibernate'in en son sürümünü bagajdan çıkarmak beni olmam gereken yere getirdi. En son koda sahip bir enum için örnek bir eşleme şöyledir:

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

Özel tür, onu .kullanmak yerine numaralandırmanın bir örneği olarak ele alınmaya zorlar GenericEnumMapper<TEnum>.

Aslında, bir dizgeyi sürdüren bir enum eşleştiricisi ile bir kural olarak ayarlayabilmeniz gereken bir şey gibi görünen bir int olarak devam eden bir eşleştirici arasında değişiklik yapabilmek için bir yama göndermeyi düşünüyorum.


Bu, son faaliyetimde ortaya çıktı ve bunu kolaylaştırmak için Fluent NHibernate'in yeni sürümlerinde işler değişti.

Tüm numaralandırmaların tamsayı olarak eşlenmesini sağlamak için artık aşağıdaki gibi bir kural oluşturabilirsiniz:

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

O zaman eşlemeniz yalnızca şöyle olmalıdır:

Map(quote => quote.Status);

Konvansiyonu Fluent NHibernate haritanıza böyle eklersiniz;

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

3
varsayılan olarak "int modu" ile. Kim numaralandırmayı dizeler olarak sürdürüyor ?!
Andrew Bullock

4
Zaten içinde dize değerleri olan eski bir veritabanı olabilir
Chris Haines

4
+1 hainesy. @ Andrew Bullock: Sorunuzun cevabı: gerçek dünya veritabanları ile uğraşan herkes.
Sky Sanders

FN'de herhangi bir IProperty arayüzü var mı?
Tien Do

40

Boş değer atanabilir numaralandırmaları (gibi ExampleEnum? ExampleProperty) unutmayın ! Ayrı ayrı kontrol edilmeleri gerekir. Yeni FNH tarzı konfigürasyonla şu şekilde yapılır:

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

4
+1 Bu ilave için! İlk sürüm, boş değer atanabilir numaralandırmalar için çalışmaz (dizeler olarak kalırlar).
longda

@SztupY Veritabanındaki sütun türü int? Ve tür, Bayrakları kabul ettiğinde? Gibi:MyEnum.Active | MyEnum.Paused
ridermansb

@RidermandeSousaBarbosa: Bayraklar için burayı kontrol edin: stackoverflow.com/questions/2805661/…
SztupY

25

bir enum özelliğini int değeriyle şu şekilde eşledim:

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

benim için çalışıyor!


2
En basit cevabı verdiğiniz için teşekkürler
Mike

Bununla ilgili tek endişem, her numaraya uygulamayı hatırlamanız gerektiğidir. Sözleşmeler bunun için yaratıldı.
Garry Shutler

Bu okumak için çalışıyor, ancak bir ölçüt sorgusunu denediğimde başarısız oldu. Yine de denediğim her durumda bir kongre oluşturmak (bu sorunun cevabına bakın) işe yaradı.
Thomas Bratt

Harika olduğunu düşündüm - ama bu sorunlara neden olacak: bu gönderiye bakın. nhforge.org/blogs/nhibernate/archive/2008/10/20/…
UpTheCreek

@UpTheCreek Görünüşe göre bu sorun düzeltildi ve NH ekibinden James Gregory tarafından öneriliyor: mail-archive.com/fluent-nhibernate@googlegroups.com/…
Ilya Kogan

1

Otomatikleştirme ile Fluent NHibernate (ve potansiyel olarak bir IoC konteyneri) kullananlar için:

IUserTypeConvention@ Gibidir Julien bireyin yanıt yukarıda: 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 yapılandırması şu şekilde yapılandırılabilir:

    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>();
                });
    }

* Daha sonra, CreateSessionFactoryCastle Windsor gibi bir IoC'de (bir PersistenceFacility ve kurulum aracı kullanılarak) kolayca kullanılabilir. *

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

0

Bir NHibernate oluşturabilir IUserTypeve bunu CustomTypeIs<T>()özellik haritasında kullanarak belirtebilirsiniz .


0

Değerleri DB Tablonuzda int / tinyint olarak tutmalısınız. Numaranızı eşlemek için eşlemeyi doğru bir şekilde belirtmeniz gerekir. Lütfen aşağıdaki eşleme ve numaralandırma örneğine bakın,

Eşleme Sınıfı

public class TransactionMap: ClassMap Transaction
{
    genel İşlem Haritası ()
    {
        // Diğer eşlemeler
        .....
        // enum için eşleme
        Harita (x => x.Status, "Durum"). CustomType ();

        Tablo ("İşlem");
    }
}

Sıralama

genel enum TransactionStatus
{
   Bekleme = 1,
   İşlenen = 2,
   RolledBack = 3,
   Engellendi = 4,
   İade edildi = 5,
   Zaten İşlenmiş = 6,
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.