0

INSERT INTO ... SELECT ...HQLでクエリを作成しようとしています。ただし、挿入しているクラスには<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]

他に何か提案はありますか?

4

3 に答える 3

2

HQL はエンティティの取得に関するものであり、レコードの取得やレコードの挿入に関するものではありません。

NHibernate を使用するときは、レコードやレコードセットの観点からではなく、エンティティの観点から考える必要があります。したがって、NHibernate を使用して DB に何かを挿入する場合は、エンティティのインスタンスを作成し、NHibernate の ISession を使用してそのエンティティをデータベースに保存する必要があります。

于 2012-08-24T09:07:06.033 に答える
1

だから答えは

session.CreateSQLQuery("INSERT INTO X(A, B, C1, C2) SELECT A, B, 'foo', 'bar' FROM X data")
       .ExecuteUpdate();
于 2012-08-24T10:19:49.973 に答える
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 のエンティティを 1 秒未満で一括挿入できます。

于 2012-08-24T12:36:37.807 に答える