C# 在不调用session.Insert或session.Save的情况下获取HiLo号码
我需要使用NHibernate对SQLite数据库进行批量插入。对象的PK是HiLo int32。我尝试将NH无状态会话与session.insert一起使用,效果很好。然而,我发现使用prepared命令要快30-40%,所以我正在尝试使用它 目前我正在努力分配id(即NH HiLo)。 我在stackoverflow()上找到了一个解决方案—请参阅方法GenerateIdentifier(),但它会在每次调用时查询和更新数据库,因此这不是一个好的选择 有没有办法让它按预期的方式工作-当id生成器达到hivalue时,它应该只做一次到服务器的往返以获得新的low和hi值C# 在不调用session.Insert或session.Save的情况下获取HiLo号码,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,我需要使用NHibernate对SQLite数据库进行批量插入。对象的PK是HiLo int32。我尝试将NH无状态会话与session.insert一起使用,效果很好。然而,我发现使用prepared命令要快30-40%,所以我正在尝试使用它 目前我正在努力分配id(即NH HiLo)。 我在stackoverflow()上找到了一个解决方案—请参阅方法GenerateIdentifier(),但它会在每次调用时查询和更新数据库,因此这不是一个好的选择 有没有办法让它按预期的方式工作-当id生
public static Int64 TestNHSQLiteBulk(bool newDB)
{
int ProjectCount = 1000000;
var factory = Database.CreateSQLiteSessionFactory(newDB);
Int64 objectCount = 0;
using (var session = factory.OpenStatelessSession())
{
var connection = session.Connection;
using (var transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
// this should be removed when proper HiLo will be implemented.
var nextProject = session.CreateCriteria<Project>().SetProjection(Projections.Max<Project>(p => p.ProjectId)).UniqueResult();
int startId = (nextProject == null) ? 0 : (int)nextProject + 1;
var command = connection.CreateCommand();
command.CommandText = "Insert INTO Project (ProjectId, ProjectName) Values(?,?)";
var projectIdParameter = command.CreateParameter();
projectIdParameter.ParameterName = "ProjectId";
projectIdParameter.DbType = System.Data.DbType.Int32;
var projectNameParameter = command.CreateParameter();
projectNameParameter.ParameterName = "ProjectName";
projectNameParameter.DbType = System.Data.DbType.String;
command.Parameters.Add(projectIdParameter);
command.Parameters.Add(projectNameParameter);
command.Prepare();
for (int p = startId; p < startId + ProjectCount; p++)
{
var project = new Project()
{
ProjectName = "Project " + p
};
//found on stackoverflow, but is results a roundtrip to server on each call.
GenerateIdentifier(project, Database.savedConfig, session);
//session.Insert(project);
//using prepared command is almost 2x faster!
projectIdParameter.Value = project.ProjectId;
projectNameParameter.Value = project.ProjectName;
command.ExecuteNonQuery();
objectCount++;
}
transaction.Commit();
}
}
return objectCount;
}
//this will get the value and update the hi-lo value repository in the datastore
public static void GenerateIdentifier(object target, NHibernate.Cfg.Configuration conf, IStatelessSession session)
{
var targetType = target.GetType();
var classMapping = conf.GetClassMapping(targetType);
var impl = session.GetSessionImplementation();
var newId = classMapping.Identifier.CreateIdentifierGenerator(impl.Factory.Dialect, classMapping.Table.Catalog, classMapping.Table.Schema,
classMapping.RootClazz).Generate(impl, target);
classMapping.IdentifierProperty.GetSetter(targetType).Set(target, newId);
}
publicstaticint64-TestNHSQLiteBulk(bool-newDB)
{
int ProjectCount=1000000;
var factory=Database.CreateSQLiteSessionFactory(newDB);
Int64 objectCount=0;
使用(var session=factory.OpenStatelessSession())
{
var connection=session.connection;
使用(var事务=session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
//在实施适当的HiLo时,应将其删除。
var nextProject=session.CreateCriteria();
int startId=(nextProject==null)?0:(int)nextProject+1;
var command=connection.CreateCommand();
command.CommandText=“插入到项目(ProjectId,ProjectName)值(?,)”;
var projectdparameter=command.CreateParameter();
ProjectdParameter.ParameterName=“ProjectId”;
ProjectdParameter.DbType=System.Data.DbType.Int32;
var projectNameParameter=command.CreateParameter();
projectNameParameter.ParameterName=“ProjectName”;
projectNameParameter.DbType=System.Data.DbType.String;
command.Parameters.Add(projectdParameter);
command.Parameters.Add(projectNameParameter);
command.Prepare();
对于(int p=startId;p
您正在为每个实体创建一个新的Hilgenerator,而不是使用给定的Hilgenerator。此外,生成器通常会将自身初始化为数据库中的值,因此无需手动查询:
public static Int64 TestNHSQLiteBulk(bool newDB)
{
int ProjectCount = 1000000;
var factory = Database.CreateSQLiteSessionFactory(newDB);
var classMapping = (SingleTableEntityPersister)factory.GetClassMetadata(typeof(Project));
var generator = classMapping.IdentifierGenerator;
Int64 objectCount = 0;
using (var session = factory.OpenStatelessSession())
{
var connection = session.Connection;
using (var transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
var command = connection.CreateCommand();
command.CommandText = "Insert INTO Project (ProjectId, ProjectName) Values(?,?)";
var projectIdParameter = command.CreateParameter();
projectIdParameter.ParameterName = "ProjectId";
projectIdParameter.DbType = System.Data.DbType.Int32;
var projectNameParameter = command.CreateParameter();
projectNameParameter.ParameterName = "ProjectName";
projectNameParameter.DbType = System.Data.DbType.String;
command.Parameters.Add(projectIdParameter);
command.Parameters.Add(projectNameParameter);
command.Prepare();
for (int p = 0; p < ProjectCount; p++)
{
var projectId = (long)generator.Generate(session.GetSessionImplementation(), null);
//using prepared command is almost 2x faster!
projectIdParameter.Value = projectId;
projectNameParameter.Value = "Project" + projectId;
command.ExecuteNonQuery();
objectCount++;
}
transaction.Commit();
}
}
return objectCount;
}
publicstaticint64-TestNHSQLiteBulk(bool-newDB)
{
int ProjectCount=1000000;
var factory=Database.CreateSQLiteSessionFactory(newDB);
var classMapping=(SingleTableEntityPersister)factory.GetClassMetadata(typeof(Project));
var生成器=classMapping.IdentifierGenerator;
Int64 objectCount=0;
使用(var session=factory.OpenStatelessSession())
{
var connection=session.connection;
使用(var事务=session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
var command=connection.CreateCommand();
command.CommandText=“插入到项目(ProjectId,ProjectName)值(?,)”;
var projectdparameter=command.CreateParameter();
ProjectdParameter.ParameterName=“ProjectId”;
ProjectdParameter.DbType=System.Data.DbType.Int32;
var projectNameParameter=command.CreateParameter();
projectNameParameter.ParameterName=“ProjectName”;
projectNameParameter.DbType=System.Data.DbType.String;
command.Parameters.Add(projectdParameter);
command.Parameters.Add(projectNameParameter);
command.Prepare();
对于(int p=0;p
此外,我还发现,该命令.Prepare不能提高