我正在使用NHibernate将一些非常简单的实体映射到三个表。
我的程序需要有一个模式,它输出它将执行的SQL以插入或更新这些表,以便SQL可以保存到脚本文件中,以便稍后手动执行。
这类似于这个问题(答案非常好):How can I have NHibernate only generate the SQL without executing it?
只有那个问题是关于SELECT,我需要类似于INSERT / UPDATE。 这也需要是动态的,因为它取决于用户选项。我的意思是,当我的程序执行时:
session.Save(entity);
有时我需要它来命中数据库,有时我需要输出它将执行的SQL。
这一切都可能吗?
答案 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;
}
}