如何将特定的.hbm.xml文件添加到nhibernate配置以在导出模式中使用

时间:2012-11-20 16:51:15

标签: c# nhibernate triggers fluent schemaexport

我正在使用nhibernate +流利,我有这段代码

FluentConfiguration fc = Fluently.Configure()
            .Database(MySQLConfiguration.Standard.ConnectionString(connectionString).ShowSql()
            .Dialect<NHibernate.Dialect.MySQL5Dialect>().Driver<NHibernate.Driver.MySqlDataDriver>())
            .Mappings(m => m.FluentMappings
                .AddFromAssemblyOf<UsuarioMap>()
                .Conventions.Add(PrimaryKey.Name.Is(a => string.Concat("Id", a.EntityType.Name)))
                .Conventions.Add(ForeignKey.Format((x, y) => string.Concat("Id", y.Name))))
            .ExposeConfiguration(BuildSchema);

这会添加我的地图文件中的映射,稍后我会使用公开的配置来导出模式

现在我需要添加一个特定的.hbm.xml文件,以便在我的数据库中创建一个触发器,我不知道如何,我已经编写了.hbm.xml文件,它看起来像这样

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <database-object>
    <create>
    CREATE TRIGGER borradoUsuario BEFORE DELETE ON activaciones
    FOR EACH ROW BEGIN set @idUsuario = OLD.IdUsuario;
    SELECT IdHistorialEstado FROM Usuarios WHERE IdUsuario = @idUsuario INTO @IdHistorial;
    SELECT IdDomicilio FROM Usuarios WHERE IdUsuario = @idUsuario INTO @idDomicilio;
    DELETE FROM usuarios WHERE IdUsuario = @idUsuario;
    DELETE FROM domicilios WHERE IdDomicilio = @IdDomicilio;
    DELETE FROM historialestado WHERE IdHistorialEstado = @idHistorial;
    DELETE FROM detallehistorialestado WHERE idHistorialEstado = @idHistorial;
    DELETE FROM inmobiliarias WHERE IdInmobiliaria = @idUsuario;
    DELETE FROM particulares WHERE IdParticular = @idUsuario;
    DELETE FROM moderadores WHERE IdModerador = @idUsuario;
    END
</create>

<drop>
</drop>

我希望我能在这里得到一些帮助= /

我已转移到另一个方法,我没有从AbstractAuxiliaryDatabaseObject扩展的类,它知道创建和删除脚本:

public class BorradoUsuarioTrigger : AbstractAuxiliaryDatabaseObject{

    public override string SqlCreateString(Dialect dialect, IMapping p, string defaultCatalog, string defaultSchema){
//The drop is important, because the shema export calls and executes this twice.   


    return @"
        DROP TRIGGER IF EXISTS borradoUsuarioTrigger;
        DELIMITER $$
        CREATE TRIGGER borradoUsuarioTrigger BEFORE DELETE ON activaciones FOR EACH ROW 
        BEGIN 
            DECLARE idHist INTEGER;
            DECLARE idDom INTEGER;
            SET idHist = (SELECT IdHistorialEstado FROM Usuarios WHERE IdUsuario = OLD.IdUsuario);
            SET idDom = (SELECT IdDomicilio FROM Usuarios WHERE IdUsuario = OLD.IdUsuario);
            DELETE FROM domicilios WHERE IdDomicilio = @idDom;
            DELETE FROM historialestado WHERE IdHistorialEstado = @idHist;
            DELETE FROM detallehistorialestado WHERE idHistorialEstado = @idHist;
            DELETE FROM inmobiliarias WHERE IdInmobiliaria = OLD.idUsuario;
            DELETE FROM particulares WHERE IdParticular = OLD.idUsuario;
            DELETE FROM moderadores WHERE IdModerador = OLD.idUsuario;
            DELETE FROM usuarios WHERE IdUsuario = OLD.idUsuario;
        END$$";
    }

    public override string SqlDropString(Dialect dialect, string defaultCatalog, string defaultSchema){
    return @"DROP TRIGGER IF EXISTS borradoUsuarioTrigger";
    }

    public void AddDialectScope(string dialectName){
    throw new NotImplementedException();
    }

    public bool AppliesToDialect(Dialect dialect){
    return true;
    }

    public void SetParameterValues(IDictionary<string, string> parameters){
    base.SetParameterValues(parameters);
    }
}

我认为我接近我需要的东西,但它仍然无效,我在最深刻的例外中得到以下信息:

"Parameter @idDom must be defined"

我认为这是因为我正在尝试为sql创建脚本返回一个硬编码字符串,但我不知道,有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

终于得到了答案:

知道sql脚本的类看起来像这样

public class BorradoUsuarioTrigger : AbstractAuxiliaryDatabaseObject
{
    public override string SqlCreateString(Dialect dialect, IMapping p, string defaultCatalog, string defaultSchema){
    //The drop is important, because the shema export calls and executes this twice.   
    this.Parameters.Add("idHist", "(SELECT IdHistorialEstado FROM Usuarios WHERE IdUsuario = OLD.IdUsuario)");
    this.Parameters.Add("idDom", "(SELECT IdDomicilio FROM Usuarios WHERE IdUsuario = OLD.IdUsuario)");

    StringBuilder builder = new StringBuilder();

    builder.AppendLine("DROP TRIGGER IF EXISTS borradoUsuarioTrigger;");
    builder.AppendLine("CREATE TRIGGER borradoUsuarioTrigger BEFORE DELETE ON activaciones FOR EACH ROW ");
    builder.AppendLine("BEGIN ");
    builder.AppendLine("DELETE FROM domicilios WHERE IdDomicilio = " + this.Parameters["idDom"] + "; ");
    builder.AppendLine("DELETE FROM historialestado WHERE IdHistorialEstado = " + this.Parameters["idHist"] + "; ");
    builder.AppendLine("DELETE FROM detallehistorialestado WHERE idHistorialEstado = " + this.Parameters["idHist"] + "; ");
    builder.AppendLine("DELETE FROM inmobiliarias WHERE IdInmobiliaria = OLD.idUsuario; ");
    builder.AppendLine("DELETE FROM particulares WHERE IdParticular = OLD.idUsuario; ");
    builder.AppendLine("DELETE FROM moderadores WHERE IdModerador = OLD.idUsuario; ");
    builder.AppendLine("DELETE FROM usuarios WHERE IdUsuario = OLD.idUsuario; ");
    builder.AppendLine("END ");

    return builder.ToString();
    }

    public override string SqlDropString(Dialect dialect, string defaultCatalog, string defaultSchema)
    {
        return @"DROP TRIGGER IF EXISTS borradoUsuarioTrigger";
    }

    public void AddDialectScope(string dialectName)
    {
        throw new NotImplementedException();
    }

    public bool AppliesToDialect(Dialect dialect)
    {
        return true;
    }

    public void SetParameterValues(IDictionary<string, string> parameters)
    {
        base.SetParameterValues(parameters);
    }
}

,流利的配置如下:

        FluentConfiguration fc = Fluently.Configure()
            .Database(MySQLConfiguration.Standard.ConnectionString(connectionString).ShowSql()
            .Dialect<NHibernate.Dialect.MySQL5Dialect>().Driver<NHibernate.Driver.MySqlDataDriver>())
            .Mappings(m => m.FluentMappings
                .AddFromAssemblyOf<UsuarioMap>()
                .Conventions.Add(PrimaryKey.Name.Is(a => string.Concat("Id", a.EntityType.Name)))
                .Conventions.Add(ForeignKey.Format((x, y) => string.Concat("Id", y.Name))))
            .ExposeConfiguration(conf => conf.AddAuxiliaryDatabaseObject(new BorradoUsuarioTrigger()))
            .ExposeConfiguration(BuildSchema);