Fluent nHibernate,Hi-Lo表,每行实体使用约定

Fluent nHibernate,Hi-Lo表,每行实体使用约定,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,有没有一种方法可以通过约定指定一个用于Hi Lo值的表,每个实体都有一个每行条目(同时仍然让nHibernate为您创建表结构)?我想复制Phil Haydon在博客上写的内容,但不必手动管理表。目前,只有在您已经为表中的“TableKey”创建了适当的条目的情况下,才能将他的每表行代码迁移到其自己的约定 或者,这是否可以通过XML映射实现 如果所有其他方法都失败了,那么在他的一个代码映射帖子中使用自定义生成器(la?Fabio Maulo)是唯一合适的选择 代码映射示例: mapper.Bef

有没有一种方法可以通过约定指定一个用于Hi Lo值的表,每个实体都有一个每行条目(同时仍然让nHibernate为您创建表结构)?我想复制Phil Haydon在博客上写的内容,但不必手动管理表。目前,只有在您已经为表中的“TableKey”创建了适当的条目的情况下,才能将他的每表行代码迁移到其自己的约定

或者,这是否可以通过XML映射实现

如果所有其他方法都失败了,那么在他的一个代码映射帖子中使用自定义生成器(la?

Fabio Maulo)是唯一合适的选择

代码映射示例:

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())
        })));
对于FluentNHibernate,您可以执行以下操作:

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));
    }
}
此外,Fabio还解释了如何使用
IAuxiliaryDatabaseObject
创建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 
        });
}

对于Fluent NHibernate的用户,Anthony Dewhist在这里发布了一个很好的解决方案:

在Anthony Dewhist已经很好的解决方案的基础上,我总结了以下内容,这增加了一些改进:

  • 添加接受条件,这样它就不会尝试处理非整数Id类型(例如Guid),也不会踩到显式设置了生成器的Id映射
  • 脚本生成需要考虑方言
公共类HiLoIdGeneratorConvention:IIdConvention,IIdConventionAcceptance
{
public const string EntityColumnName=“entity”;
公共常量字符串MaxLo=“500”;
公共无效接受(IAcceptanceCriteria标准)
{
标准
.Expect(x=>x.Type==typeof(int)| | x.Type==typeof(uint)| | x.Type==typeof(long)| | x.Type==typeof(ulong))//HiLo仅适用于整型
.Expect(x=>x.Generator.EntityType==null);//尚未映射特定的生成器
}
public void Apply(IIdentityInstance实例)
{
instance.GeneratedBy.HiLo(TableGenerator.DefaultTableName、TableGenerator.DefaultColumnName、MaxLo、,
builder=>builder.AddParam(TableGenerator.Where,string.Format(“{0}='{1}',EntityColumnName,instance.EntityType.FullName));
}
公共静态void CreateHighLowScript(NHibernate.Cfg.Configuration配置)
{
var方言=Activator.CreateInstance(Type.GetType(config.GetProperty(NHibernate.Cfg.Environment.dial)),作为方言;
var script=新的StringBuilder();
AppendFormat(“从{0};删除”,TableGenerator.DefaultTableName);
script.AppendLine();
script.AppendFormat(“ALTER TABLE{0}{1}{2}{3}NOT NULL;”,TableGenerator.DefaultTableName,dialogue.AddColumnString,EntityColumnName,dialogue.GetTypeName(SqlTypeFactory.GetAnsiString(128));
script.AppendLine();
script.AppendFormat(“在{0}({1}ASC);”上创建非聚集索引IX{0}{1}”,TableGenerator.DefaultTableName,EntityColumnName);
script.AppendLine();
if(方言支持SqlBatches)
{
script.AppendLine(“GO”);
script.AppendLine();
}
foreach(config.ClassMappings.Select(m=>m.entityName.Distinct()中的var entityName)
{
AppendFormat(“插入[{0}]({1},{2})值({3}',1);”,TableGenerator.DefaultTableName,EntityColumnName,TableGenerator.DefaultColumnName,entityName);
script.AppendLine();
}
if(方言支持SqlBatches)
{
script.AppendLine(“GO”);
script.AppendLine();
}
config.AddAuxiliaryDatabaseObject(新的SimpleAuxiliaryDatabaseObject(script.ToString(),null));
}
}
configuration.AddAuxiliaryDatabaseObject(CreateHighLowScript(
    modelInspector, Assembly.GetExecutingAssembly().GetExportedTypes()));