我怎样才能让NHibernate给出它为插入/更新生成的SQL而不是执行它?

时间:2012-05-28 15:18:49

标签: c# nhibernate fluent-nhibernate

我正在使用NHibernate将一些非常简单的实体映射到三个表。

我的程序需要有一个模式,它输出它将执行的SQL以插入或更新这些表,以便SQL可以保存到脚本文件中,以便稍后手动执行。

这类似于这个问题(答案非常好):How can I have NHibernate only generate the SQL without executing it?

只有那个问题是关于SELECT,我需要类似于INSERT / UPDATE。 这也需要是动态的,因为它取决于用户选项。我的意思是,当我的程序执行时:

        session.Save(entity);

有时我需要它来命中数据库,有时我需要输出它将执行的SQL。

这一切都可能吗?

3 个答案:

答案 0 :(得分:1)

这是不可能的,因为这样的主要目的是让NHM像NHibernate一样,但是出于测试目的,如果你想检查Nhibernate生成的查询,那么在app.config中使用这个记录器,    <logger name="NHibernate.SQL"> <level value="ALL" /> <appender-ref ref="NHibernateRollingLogFileAppender" /> </logger>

在那时,当你对项目进行检查时,它应该生成logfile_nhibernate.txt,你会看到所有生成的查询。

答案 1 :(得分:0)

不幸的是,这是不可能的。

答案 2 :(得分:0)

如果您想要这么做,请查看下面的代码。

public IDbCommand CreateInsertCommand(object entity)
{
    var entityTuplizer = GetTuplizer(_sessionMetadata.SessionImplementor);
    var values = entityTuplizer.GetPropertyValuesToInsert(entity, new Dictionary<object, object>(), _sessionMetadata.SessionImplementor);

    var notNull = GetPropertiesToInsert(values);
    var sql = GenerateInsertString(true, notNull);
    var insertCommand = _sessionMetadata.Batcher.Generate(sql.CommandType, sql.Text, sql.ParameterTypes);

    Dehydrate(null, values, notNull, _propertyColumnInsertable, 0, insertCommand, _sessionMetadata.SessionImplementor);
    InfraUtil.FixupGuessedType(insertCommand);

    return insertCommand;
}

更多代码可引导您找到可行的解决方案

public class SessionMetadata
{
    private static readonly Type KeyType = typeof(ActiveRecordBase);

    private ISessionFactoryHolder _sessionFactoryHolder;
    private ISessionFactory _sessionFactory;
    private ISessionFactoryImplementor _sessionFactoryImplementor;
    private Configuration _configuration;
    private ISession _currentSession;
    private ISessionImplementor _sessionImplementor;
    private DriverBase _driver;
    private NonBatchingBatcher _batcher;
    private IMapping _mapping;

    public ISessionFactoryHolder SessionFactoryHolder
    {
        get { return _sessionFactoryHolder ?? (_sessionFactoryHolder = ActiveRecordMediator.GetSessionFactoryHolder()); }
    }

    public ISessionFactory SessionFactory
    {
        get { return _sessionFactory ?? (_sessionFactory = SessionFactoryHolder.GetSessionFactory(KeyType)); }
    }

    public ISessionFactoryImplementor SessionFactoryImplementor
    {
        get { return _sessionFactoryImplementor ?? (_sessionFactoryImplementor = (ISessionFactoryImplementor)SessionFactory); }
    }

    public DriverBase Driver
    {
        get { return _driver ?? (_driver = (DriverBase)SessionFactoryImplementor.ConnectionProvider.Driver); }
    }

    public NonBatchingBatcher Batcher
    {
        get { return _batcher ?? (_batcher = (NonBatchingBatcher)SessionImplementor.Batcher); }
    }

    public Configuration Configuration
    {
        get { return _configuration ?? (_configuration = SessionFactoryHolder.GetConfiguration(KeyType)); }
    }

    public ISession CurrentSession
    {
        get { return _currentSession ?? (_currentSession = SessionScope.Current.GetSession(SessionFactory)); }
    }

    public ISessionImplementor SessionImplementor
    {
        get { return _sessionImplementor ?? (_sessionImplementor = CurrentSession.GetSessionImplementation()); }
    }

    public IMapping Mapping
    {
        get { return _mapping ?? (_mapping = SessionFactoryImplementor); }
    }
}

public class EntityMetadata
{
    private readonly SessionMetadata _sessionMetadata;
    private readonly Type _entityType;
    private PersistentClass _persistentClass;
    private IEntityPersister _entityPersister;

    public EntityMetadata(Type entityType, SessionMetadata sessionMetadata)
    {
        _sessionMetadata = sessionMetadata;
        _entityType = entityType;
    }

    public SessionMetadata SessionMetadata
    {
        get { return _sessionMetadata; }
    }

    public PersistentClass PersistentClass
    {
        get { return _persistentClass ?? (_persistentClass = SessionMetadata.Configuration.GetClassMapping(_entityType)); }
    }

    public IEntityPersister EntityPersister
    {
        get { return _entityPersister ?? (_entityPersister = SessionMetadata.SessionFactoryImplementor.GetEntityPersister(PersistentClass.EntityName)); }
    }
}

public class ExtractSql: SingleTableEntityPersister
{
    private readonly SessionMetadata _sessionMetadata;
    private readonly EntityMetadata _entityMetadata;
    private readonly IEntityPersister _entityPersister;
    private readonly bool[][] _propertyColumnInsertable;
    private readonly bool[][] _propertyColumnUpdateable;

    public ExtractSql(EntityMetadata entityMetadata)
        : base(entityMetadata.PersistentClass, null, entityMetadata.SessionMetadata.SessionFactoryImplementor, entityMetadata.SessionMetadata.Mapping)
    {
        if (entityMetadata == null) throw new ArgumentNullException("entityMetadata");
        _sessionMetadata = entityMetadata.SessionMetadata;
        _entityMetadata = entityMetadata;

        _entityPersister = _entityMetadata.EntityPersister;

        var hydrateSpan = _entityPersister.EntityMetamodel.PropertySpan;
        _propertyColumnUpdateable = new bool[hydrateSpan][];
        _propertyColumnInsertable = new bool[hydrateSpan][];

        var i = 0;
        foreach (var prop in _entityMetadata.PersistentClass.PropertyClosureIterator)
        {
            _propertyColumnInsertable[i] = prop.Value.ColumnInsertability;
            _propertyColumnUpdateable[i] = prop.Value.ColumnUpdateability;

            i++;
        }
    }

    protected override bool UseDynamicUpdate
    {
        get { return true; }
    }

    protected override bool UseDynamicInsert
    {
        get { return true; }
    }

    public IDbCommand CreateInsertCommand(object entity)
    {
        var entityTuplizer = GetTuplizer(_sessionMetadata.SessionImplementor);
        var values = entityTuplizer.GetPropertyValuesToInsert(entity, new Dictionary<object, object>(), _sessionMetadata.SessionImplementor);

        var notNull = GetPropertiesToInsert(values);
        var sql = GenerateInsertString(true, notNull);
        var insertCommand = _sessionMetadata.Batcher.Generate(sql.CommandType, sql.Text, sql.ParameterTypes);

        Dehydrate(null, values, notNull, _propertyColumnInsertable, 0, insertCommand, _sessionMetadata.SessionImplementor);
        InfraUtil.FixupGuessedType(insertCommand);

        return insertCommand;
    }
}