2009-12-09 31 views
6

Sütun sırasını çoklu sütun dizininde nasıl değiştirebilirim?
yani:Akıcı-nhibernate kullanarak sütun sırasını çoklu sütun dizininde nasıl değiştirebilirim?

mapping.References(x => x.SomeReference).SetAttribute("index", "IX_index"); 
mapping.Map(x => x.SomeField).SetAttribute("index", "IX_index"); 

aşağıdaki şema üretir:

create index IX_index on ApplicantProgramDatas (SomeField, SomeReferenceId) 

Ama almak istiyorum: Ben imkansız olduğunu tahmin

create index IX_index on ApplicantProgramDatas (SomeReferenceId, SomeField) 
+0

+1 sonunda bunu yapmak için bir yol bulmak istediniz:

Sen NHibernate docs yardımcı veritabanı nesneler hakkında daha fazla bilgi bulabilirim?Aynı problemi yaşıyorum. – Groo

+1

Haritalama beyanlarının sırasını değiştirmeyi denediniz mi? (Çalışırsa bile biraz bir şekerleme!) – UpTheCreek

+0

@UpTheCreek: Ben'in aşağıda dediği gibi, işe yaramadığını düşünüyorum. Ve birden fazla sütun dizini birden fazla olsaydı, bu yaklaşım başarısız olur, çünkü tek bir sütunu * tüm * dizinlerindeki en büyük dizin sütunu olmasını zorlar. – Groo

cevap

4

yeniden düşünün.

<hibernate-mapping xmlns="urn:nhiernate-mapping-2.2"> 
    <database-object> 
    <create>VALID SQL</create> 
    <drop>VALID SQL</create> 
    </database-object> 
</hibernate-mapping> 

N.B.: Bir hbm.xml dosyasında

< veritabanı nesnesi >, aynı hbm.xml dosyasında, sınıf tanımlarını, tetikleyicileri, vb. Uygulayacağınız nesneyle tutmanıza olanak veren bir sınıf eşlemesinden önce veya sonra gidebilir. Eğer Fluent NHibernate kullanıyoruz, IAuxiliaryDatabaseObject muhtemelen sizin için daha iyi çalışır göz önüne alındığında

namespace NHibernate.Mapping { 
    public interface IAuxiliaryDatabaseObject : IRelationalModel { 
     void AddDialectScope(string dialectName); 
     bool AppliesToDialect(Dialect dialect); 
     void SetParameterValues(IDictionary<string, string> parameters); 
    } 
    public interface IRelationalModel { 
     string SqlCreateString(Dialect dialect, IMapping p, string defaultCatalog, string defaultSchema); 
     string SqlDropString(Dialect dialect, string defaultCatalog, string defaultSchema); 
    } 
} 

:

Diğer seçenek

NHibernate.Mapping.IAuxiliaryDatabaseObject olduğunu. Yapılandırırken yapılandırmanızı görün ve sonra da şu numarayı arayın:

N.B. NHibernate.Mapping.SimpleAuxiliaryDatabaseObject, NHibernate'nin bir parçasıdır. Yapmanız gereken tek şey, bir veritabanı nesnesi için oluşturma/bırak komutları sağlamaksa, kendiniz yazmak zorunda değilsiniz.

Fluent NHibernate kod tabanına hızlıca baktım ve IAuxiliaryDatabaseObject için doğrudan destek görmedim. Dolayısıyla, yapılandırma nesnesini açığa çıkarma ve tüm IAuxiliaryDatabaseObjects öğelerinizi kendiniz tedarik etme sorunudur. Eşleme derlemenizi tarayan bazı kodları IAuxiliaryDatabaseObject uygulayan türleri aramak ve sonra cfg.AddAuxiliaryDatabaseObject (obj) 'a geçmek için üzerinde gezinmek için kod yazmak çok zor olmaz.

http://nhibernate.info/doc/nh/en/index.html#mapping-database-object

3

. kaynaklardan önce 'FluentNHibernate.MappingModel.MappedMembers.AcceptVisitor()' dolaşır özellikleri: Sonuç olarak

 foreach (var collection in Collections) 
      visitor.Visit(collection); 

     foreach (var property in Properties) 
      visitor.Visit(property); 

     foreach (var reference in References) 
      visitor.Visit(reference); 

, her zaman çok sütunlu endeksindeki kaynaklardan önce özelliklere sahip olacaktır.

BTW ORMs hiçbiri size

+0

Teşekkürler. Bu durumda, yapılandırmaya bazı özel (el ile yazılmış) şema eklemenin bir yolunu biliyor musunuz? DB oluşturma ile ilgili tüm SQL'i tek bir yerde bulundurmayı tercih ederim. NHibernate şemanın geri kalanını oluşturduktan sonra, sadece indeks eklemek için düz SQL'i çalıştırabilirim. – Groo

2

beni SchemaExport geçersiz kılmak önerelim, vb kümelenmiş süzülür gibi önemsiz olmayan dizin seçeneklerini ayarlama yeteneğini verecektir. Yansıma yoluyla özel alan erişimcisi vardır, tam güven modunu gerektirir. Bu yaklaşım ihtiyaçlarınızı uygun değilse, sen < veritabanı nesnesini > veya IAuxiliaryDatabaseObject kullanarak NHibernate içinde bir dizin tanımlayabilirsiniz SchemaExport (nispeten hafif sınıf)


using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Reflection; 
using System.Text; 
using FluentNHibernate.Cfg; 
using FluentNHibernate.Cfg.Db; 
using FluentNHibernate.Mapping; 
using NHibernate.Cfg; 
using NHibernate.Tool.hbm2ddl; 

namespace FluentNHib 
{ 

    public class Master 
    { 
     public int Id { get; set; } 
    } 

    public class Child 
    { 
     public int Id { get; set; } 
     [MCIndex("A", 0)] 
     public Master Master { get; set; } 
     [MCIndex("A", 1)] 
     public string Name { get; set; } 
    } 

    public class MCIndexAttribute : Attribute 
    { 
     public string indexName; 
     public int indexOrder; 

     public MCIndexAttribute(string indexName, int i) 
     { 
      this.indexName = indexName; 
      this.indexOrder = i; 
     } 
    } 

    public class MasterMap : ClassMap 
    { 
     public MasterMap() 
     { 
      Id(x => x.Id); 
     } 
    } 

    public class ChildMap : ClassMap 
    { 
     public ChildMap() 
     { 
      Id(x => x.Id); 
      References(x => x.Master).Index("A"); 
      Map(x => x.Name).Index("A"); 

     } 
    } 

    class MySchemaExport : SchemaExport 
    { 
     internal struct MCIndexField 
     { 
      internal int index; 
      internal string Name; 

     } 

     internal class MCIndex 
     { 
      internal string IndexName; 
      public readonly IList fields = new List(); 
      public string Table; 

      public void AddField(string name, int indexOrder) 
      { 
       fields.Add(new MCIndexField {index = indexOrder, Name = name}); 
      } 
     } 

     private readonly Dictionary indexes = new Dictionary(); 

     MCIndex ByName(string name, string table) 
     { 
      MCIndex result; 
      if (!indexes.TryGetValue(name, out result)) 
      { 
       result = new MCIndex 
        { 
         IndexName = name 
        }; 
       indexes.Add(name, result); 
      } 
      return result; 
     } 

     public MySchemaExport(Configuration cfg) : base(cfg) 
     { 
      foreach (var type in typeof(ChildMap).Assembly.GetTypes()) 
      { 
       foreach (var prop in type.GetProperties()) 
       { 
        var attr = prop.GetCustomAttributes(typeof (MCIndexAttribute), true); 
        if (attr.Length == 1) 
        { 
         var attribute = (MCIndexAttribute) attr[0]; 
         ByName(attribute.indexName, type.Name).AddField(prop.Name, attribute.indexOrder); 
        } 
       } 
      } 


      var createSqlProp = typeof(SchemaExport).GetField("createSQL", BindingFlags.NonPublic | BindingFlags.Instance); 
      var wasSql = createSqlProp.GetValue(this); 

      var sb = new StringBuilder(); 
      sb.AppendLine(""); 
      foreach (var mcIndex in indexes) 
      { 
       sb.AppendLine(string.Format("create index {0} on {1} ({2})", mcIndex.Value.IndexName, mcIndex.Value.Table, mcIndex.Value.fields)); 
      } 
      createSqlProp.SetValue(this, wasSql + sb.ToString()); 
     } 
    } 

    class Program 
    { 

     private static void BuildSchema(Configuration config) 
     { 
      new MySchemaExport(config) 
       .Create(s => 
          { 
           Debug.WriteLine(s); 
          }, true); 
     } 

     const string fileName = "c:\\temp\\temp.fdb"; 

     private static string GetConnectionString() 
     { 
      const string userName = "sysdba"; 
      const string password = "masterkey"; 
      return String.Format("ServerType=1;User={0};Password={1};Dialect=3;Database={2}", userName, password, fileName); 
     } 

     private static FluentConfiguration Configurate() 
     { 
      var fbc = new FirebirdConfiguration(); 
      return Fluently.Configure() 
      .Database(fbc.ShowSql().ConnectionString(GetConnectionString())) 
       .Mappings(m => m.FluentMappings 
        .AddFromAssemblyOf() 
       ) 
       .ExposeConfiguration(BuildSchema); 
     } 

     static void Main(string[] args) 
     { 
      FluentConfiguration fluentConfiguration = Configurate(); 

      Configuration cfg = fluentConfiguration.BuildConfiguration(); 
     } 
    } 
}
+0

Teşekkürler, kötü bir öneri değil. Ancak birkaç not: a) Bence jenerik parantezlerinizin kaybolduğunu biliyorum '<>', b) 'createSQL', FluentHib’de bir dizi dizgi döndürüyor gibi görünüyor. 1.1, c) aslında indeks numarasına göre öznitelikleri sıralamıyorsunuz, d) 'alanlar 'listesi, sb.AppendLine'de kendiliğinden düzgün bir şekilde işlenmeyecektir. Bunları kolayca düzeltebilirim, ama aslında gerçek varlıklar yerine eşleme sınıflarımdaki dizinleri seçmeyi tercih ederim, bu yüzden muhtemelen onları orada taşımak için iyi bir kısmını yeniden yazacağım. Yine de sorumu yanıtladı ve bana iyi bir fikir verdi. – Groo

İlgili konular