2012-07-09 13 views
5

Czy istnieje sposób określenia tabeli do użycia dla wartości Hi-Lo, przy czym każda jednostka ma wpis w wierszu, za pośrednictwem konwencji (podczas nadal mając nHibernate utworzyć dla ciebie strukturę stołu)? Chciałbym powtórzyć, co Phil Haydon napisał na blogu na temat here, ale bez konieczności ręcznego zarządzania stolikiem. W obecnej wersji migracja kodu wiersza na tabelę do własnej konwencji będzie działać tylko wtedy, gdy już masz już utworzone odpowiednie wpisy dla tabeli "TableKey".Płynna nHibernacja, tabela Hi-Lo z jednostką-wierszem przy użyciu konwencji

Czy jest to możliwe za pomocą odwzorowań XML?

A jeśli wszystko inne zawiedzie, czy jest jedyną odpowiednią opcją użycia niestandardowego generatora, a la this post?

Odpowiedz

8

Fabio Maulo talked about this w jednym ze swoich postów mapowania kodu.

Mapowanie przez przykładzie kodu:

mapper.BeforeMapClass += (mi, type, map) => 
    map.Id(idmap => idmap.Generator(Generators.HighLow, 
     gmap => gmap.Params(new 
     { 
      table = "NextHighValues", 
      column = "NextHigh", 
      max_lo = 100, 
      where = string.Format(
       "EntityName = '{0}'", type.Name.ToLowerInvariant()) 
     }))); 

Dla FluentNhibernate, można zrobić coś takiego:

public class PrimaryKeyConvention : IIdConvention 
{ 
    public void Apply(IIdentityInstance instance) 
    { 
     var type = instance.EntityType.Name; 
     instance.Column(type + "Id"); 
     instance.GeneratedBy.HiLo(type, "NextHigh", "100", 
      x => x.AddParam("where", String.Format("EntityName = '{0}'", type)); 
    } 
} 

Również Fabio wyjaśnił, jak można użyć IAuxiliaryDatabaseObject stworzyć skrypt Hi-Lo.

private static IAuxiliaryDatabaseObject CreateHighLowScript(
    IModelInspector inspector, IEnumerable<Type> entities) 
{ 
    var script = new StringBuilder(3072); 
    script.AppendLine("DELETE FROM NextHighValues;"); 
    script.AppendLine(
     "ALTER TABLE NextHighValues ADD EntityName VARCHAR(128) NOT NULL;"); 
    script.AppendLine(
     "CREATE NONCLUSTERED INDEX IdxNextHighValuesEntity ON NextHighValues " 
     + "(EntityName ASC);"); 
    script.AppendLine("GO"); 

    foreach (var entity in entities.Where(x => inspector.IsRootEntity(x))) 
    { 
     script.AppendLine(string.Format(
     "INSERT INTO [NextHighValues] (EntityName, NextHigh) VALUES ('{0}',1);", 
     entity.Name.ToLowerInvariant())); 
    } 

    return new SimpleAuxiliaryDatabaseObject(
     script.ToString(), null, new HashedSet<string> { 
      typeof(MsSql2005Dialect).FullName, typeof(MsSql2008Dialect).FullName 
     }); 
} 

będzie go używać tak:

configuration.AddAuxiliaryDatabaseObject(CreateHighLowScript(
    modelInspector, Assembly.GetExecutingAssembly().GetExportedTypes())); 
2

Building off już doskonałe rozwiązanie Anthony Dewhirst za , Zakończyłem z następującymi, które dodaje kilka ulepszeń:

  • Dodaje kryteria akceptacji, aby nie próbował obsługiwać nieintegralnych typów identyfikatorów (np. GUID) i nie będzie stomp na odwzorowań ID, które posiada generator jawnie ustawić
  • generacja Script trwa Dialekt pod uwagę
public class HiLoIdGeneratorConvention : IIdConvention, IIdConventionAcceptance 
{ 
    public const string EntityColumnName = "entity"; 
    public const string MaxLo = "500"; 

    public void Accept(IAcceptanceCriteria<IIdentityInspector> criteria) 
    { 
     criteria 
      .Expect(x => x.Type == typeof(int) || x.Type == typeof(uint) || x.Type == typeof(long) || x.Type == typeof(ulong)) // HiLo only works with integral types 
      .Expect(x => x.Generator.EntityType == null); // Specific generator has not been mapped 
    } 

    public void Apply(IIdentityInstance instance) 
    { 
     instance.GeneratedBy.HiLo(TableGenerator.DefaultTableName, TableGenerator.DefaultColumnName, MaxLo, 
            builder => builder.AddParam(TableGenerator.Where, string.Format("{0} = '{1}'", EntityColumnName, instance.EntityType.FullName))); 
    } 

    public static void CreateHighLowScript(NHibernate.Cfg.Configuration config) 
    { 
     var dialect = Activator.CreateInstance(Type.GetType(config.GetProperty(NHibernate.Cfg.Environment.Dialect))) as Dialect; 
     var script = new StringBuilder(); 

     script.AppendFormat("DELETE FROM {0};", TableGenerator.DefaultTableName); 
     script.AppendLine(); 
     script.AppendFormat("ALTER TABLE {0} {1} {2} {3} NOT NULL;", TableGenerator.DefaultTableName, dialect.AddColumnString, EntityColumnName, dialect.GetTypeName(SqlTypeFactory.GetAnsiString(128))); 
     script.AppendLine(); 
     script.AppendFormat("CREATE NONCLUSTERED INDEX IX_{0}_{1} ON {0} ({1} ASC);", TableGenerator.DefaultTableName, EntityColumnName); 
     script.AppendLine(); 
     if (dialect.SupportsSqlBatches) 
     { 
      script.AppendLine("GO"); 
      script.AppendLine(); 
     } 
     foreach (var entityName in config.ClassMappings.Select(m => m.EntityName).Distinct()) 
     { 
      script.AppendFormat("INSERT INTO [{0}] ({1}, {2}) VALUES ('{3}',1);", TableGenerator.DefaultTableName, EntityColumnName, TableGenerator.DefaultColumnName, entityName); 
      script.AppendLine(); 
     } 
     if (dialect.SupportsSqlBatches) 
     { 
      script.AppendLine("GO"); 
      script.AppendLine(); 
     } 

     config.AddAuxiliaryDatabaseObject(new SimpleAuxiliaryDatabaseObject(script.ToString(), null)); 
    } 
} 
Powiązane problemy