我正在尝试在HQL中编写INSERT INTO ... SELECT ...
查询。但是,我插入的类在映射中包含<component>
项。例如,我的类定义可能是:
public class X
{
public virtual string A { get; set; }
public virtual string B { get; set; }
public virtual Y C { get; set; }
}
public class Y
{
public virtual string C1 { get; set; }
public virtual string C2 { get; set; }
}
可能的映射:
<class name="X">
<id type="int"><generator class="identity"/></id>
<property name="A" />
<property name="B" />
<component name="C">
<property name="C1" column="C1" />
<property name="C2" column="C2" />
</component>
</component>
</class>
如何在HQL中为此类编写插入查询?我试过了:
session.CreateQuery("INSERT INTO X(A, B, C1, C2) SELECT A, B, 'foo', 'bar' FROM X data")
.ExecuteUpdate();
这给出了错误:
NHibernate.QueryException : could not resolve property: C1 of: X
[INSERT INTO X(A, B, C1, C2) SELECT A, B, "foo", "bar" FROM X data]
我也尝试过:
session.CreateQuery("INSERT INTO X(A, B, C) SELECT A, B, :C FROM X data")
.SetParameter("C", new Y() { C1 = "foo", C2 = "bar" });
.ExecuteUpdate();
这给出了错误:
NHibernate.HibernateException : Could not determine a type for class: Y
我也尝试过:
session.CreateQuery("INSERT INTO X(A, B, C.C1, C.C2) SELECT A, B, 'foo', 'bar' FROM X data")
.ExecuteUpdate();
这给出了错误:
NHibernate.Hql.Ast.ANTLR.QuerySyntaxException : Exception of type 'Antlr.Runtime.MismatchedTreeNodeException' was thrown. near line 1, column 21
[INSERT INTO X(A, B, C.C1, C.C2) SELECT A, B, "foo", "bar" FROM X data]
还有其他建议吗?
答案 0 :(得分:2)
HQL是关于检索实体,而不是检索记录或插入记录。
使用NHibernate时,你不应该考虑记录和记录集,而应该考虑实体。 因此,如果您想使用NHibernate在数据库中插入内容,则必须创建实体实例,并使用NHibernate的ISession将该实体保存到数据库。
答案 1 :(得分:1)
所以答案是
session.CreateSQLQuery("INSERT INTO X(A, B, C1, C2) SELECT A, B, 'foo', 'bar' FROM X data")
.ExecuteUpdate();
答案 2 :(得分:1)
正如Frederik Gheysels已经回答的那样,您应该通过NHibernate会话对象创建和保存新实体。如果您要插入大量实体,我建议使用无状态会话对象来加快速度。
using (IStatelessSession statelessSession = sessionFactory.OpenStatelessSession())
using (ITransaction transaction = statelessSession.BeginTransaction())
{
foreach (var entity in entities)
statelessSession.Insert(entity);
transaction.Commit();
}
根据您插入的数据量,这可能不是一个可衡量的改进。在我目前的项目中,我可以使用无状态会话在不到一秒的时间内批量插入大约16000个实体。