Nhibernate 如何在HQL中为包含组件的类编写插入查询?

Nhibernate 如何在HQL中为包含组件的类编写插入查询?,nhibernate,hql,Nhibernate,Hql,我正在尝试编写一个插入到。。。在HQL中选择…query。但是,我插入的类在映射中包含项。例如,我的类定义可以是: 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;

我正在尝试编写一个
插入到。。。在HQL中选择…
query。但是,我插入的类在映射中包含
项。例如,我的类定义可以是:

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>
这会产生以下错误:

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();
session.CreateQuery("INSERT INTO X(A, B, C.C1, C.C2) SELECT A, B, 'foo', 'bar' FROM X data")
       .ExecuteUpdate();
这会产生以下错误:

NHibernate.HibernateException : Could not determine a type for class: Y
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]
我还尝试:

session.CreateQuery("INSERT INTO X(A, B, C) SELECT A, B, :C FROM X data")
       .SetParameter("C", new Y() { C1 = "foo", C2 = "bar" });
       .ExecuteUpdate();
session.CreateQuery("INSERT INTO X(A, B, C.C1, C.C2) SELECT A, B, 'foo', 'bar' FROM X data")
       .ExecuteUpdate();
这会产生以下错误:

NHibernate.HibernateException : Could not determine a type for class: Y
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]

还有其他建议吗?

HQL是关于检索实体的,而不是关于检索记录或插入记录的

在使用NHibernate时,您不应该考虑记录和记录集,而应该考虑实体。
因此,如果要使用NHibernate在数据库中插入某些内容,则必须创建实体的实例,并使用NHibernate的ISession将该实体保存到数据库。

HQL是关于检索实体,而不是检索记录或插入记录

在使用NHibernate时,您不应该考虑记录和记录集,而应该考虑实体。 因此,如果您想使用NHibernate在数据库中插入某些内容,您必须创建一个实体的实例,并使用NHibernate的ISession将该实体保存到数据库中。

因此答案是

session.CreateSQLQuery("INSERT INTO X(A, B, C1, C2) SELECT A, B, 'foo', 'bar' FROM X data")
       .ExecuteUpdate();
所以答案是

session.CreateSQLQuery("INSERT INTO X(A, B, C1, C2) SELECT A, B, 'foo', 'bar' FROM X data")
       .ExecuteUpdate();

正如Frederik Gheyses已经回答的那样,您应该通过NHibernate会话对象创建和保存新实体。如果要插入大量实体,我建议使用无状态会话对象来加快速度

using (IStatelessSession statelessSession = sessionFactory.OpenStatelessSession())
using (ITransaction transaction = statelessSession.BeginTransaction())
{
    foreach (var entity in entities)
        statelessSession.Insert(entity);

    transaction.Commit();
}

这可能不是一个可测量的改进,这取决于您插入的数据量。在我当前的项目中,我可以使用无状态会话在不到一秒钟的时间内批量插入大约16000个实体

正如Frederik Gheyses已经回答的,您应该通过NHibernate会话对象创建和保存新实体。如果要插入大量实体,我建议使用无状态会话对象来加快速度

using (IStatelessSession statelessSession = sessionFactory.OpenStatelessSession())
using (ITransaction transaction = statelessSession.BeginTransaction())
{
    foreach (var entity in entities)
        statelessSession.Insert(entity);

    transaction.Commit();
}

这可能不是一个可测量的改进,这取决于您插入的数据量。在我当前的项目中,我可以使用无状态会话在不到一秒钟的时间内批量插入大约16000个实体

因此,如果我的数据库包含1000个我想要复制的项目,我需要检索1000个项目并再次插入它们,而不是使用
insert-INTO。。。选择…
?这样的事情不应该用NHibernate来完成,而应该用纯SQL来完成。NHibernate是有用的,但它不是一个可以解决所有问题的灵丹妙药。(请记住,您也可以通过NHibernate执行纯SQL)因此,如果我的数据库包含1000个我要复制的项,我需要检索1000个项并再次插入它们,而不是使用
insert-INTO。。。选择…
?这样的事情不应该用NHibernate来完成,而应该用纯SQL来完成。NHibernate是有用的,但它不是一个可以解决所有问题的灵丹妙药。(请记住,您也可以通过NHibernate执行普通SQL)这是通过NH执行普通SQL,这不是HQL。这是通过NH执行普通SQL,这不是HQL。