2012-07-09 24 views
5

Có cách nào chỉ định bảng để sử dụng cho các giá trị Hi-Lo không, mỗi thực thể có mục nhập mỗi hàng, qua một quy ước (trong khi vẫn còn nHibernate tạo cấu trúc bảng cho bạn)? Tôi muốn nhân rộng những gì Phil Haydon viết blog về here, nhưng không phải tự quản lý bảng. Khi nó đứng, việc di chuyển mã hàng mỗi bảng của mình sang quy ước riêng của nó sẽ chỉ hoạt động nếu bạn đã tạo các mục thích hợp cho 'TableKey' trong bảng đã có.Fluent nHibernate, bảng Hi-Lo với thực thể mỗi hàng bằng cách sử dụng quy ước

Hoặc, điều này có thể thực hiện được thông qua ánh xạ XML không?

Và nếu mọi thứ khác không thành công, là tùy chọn thích hợp duy nhất khác để sử dụng trình tạo tùy chỉnh, la this post?

Trả lời

8

Fabio Maulo talked about this trong một trong các bài đăng theo từng mã của anh ấy.

Mapping bởi mã ví dụ:

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

Đối FluentNHibernate, bạn có thể làm một cái gì đó như:

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

Ngoài ra, Fabio giải thích làm thế nào bạn có thể sử dụng để tạo ra IAuxiliaryDatabaseObject Hi-Lo kịch bản.

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ạn sẽ sử dụng nó như thế này:

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

Building tắt của giải pháp đã xuất sắc Anthony Dewhirst của , Tôi đã kết thúc với những điều sau, có thêm một vài cải tiến:

  • Thêm Tiêu chí chấp nhận để nó không cố xử lý các loại Id không tách rời (ví dụ: Guid) và sẽ không dậm trên ánh xạ Id trong đó có một máy phát điện một cách rõ ràng thiết
  • hệ Script mất Dialect xem xét
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)); 
    } 
} 
Các vấn đề liên quan