sql >> データベース >  >> RDS >> Sqlserver

`SqlDbType.Structured`を使用してNHibernateでテーブル値パラメーターを渡すことは可能ですか?

    私の最初のアドホックなアイデアは、独自のITypeを実装することでした。 。

    public class Sql2008Structured : IType {
        private static readonly SqlType[] x = new[] { new SqlType(DbType.Object) };
        public SqlType[] SqlTypes(NHibernate.Engine.IMapping mapping) {
            return x;
        }
    
        public bool IsCollectionType {
            get { return true; }
        }
    
        public int GetColumnSpan(NHibernate.Engine.IMapping mapping) {
            return 1;
        }
    
        public void NullSafeSet(DbCommand st, object value, int index, NHibernate.Engine.ISessionImplementor session) {
            var s = st as SqlCommand;
            if (s != null) {
                s.Parameters[index].SqlDbType = SqlDbType.Structured;
                s.Parameters[index].TypeName = "IntTable";
                s.Parameters[index].Value = value;
            }
            else {
                throw new NotImplementedException();
            }
        }
    
        #region IType Members...
        #region ICacheAssembler Members...
    }
    

    これ以上のメソッドは実装されていません。 throw new NotImplementedException(); 残りのすべてにあります。次に、IQueryの簡単な拡張機能を作成しました 。

    public static class StructuredExtensions {
        private static readonly Sql2008Structured structured = new Sql2008Structured();
    
        public static IQuery SetStructured(this IQuery query, string name, DataTable dt) {
            return query.SetParameter(name, dt, structured);
        }
    }
    

    私の典型的な使用法は

    です
    DataTable dt = ...;
    ISession s = ...;
    var l = s.CreateSQLQuery("EXEC some_sp @id = :id, @par1 = :par1")
                .SetStructured("id", dt)
                .SetParameter("par1", ...)
                .SetResultTransformer(Transformers.AliasToBean<SomeEntity>())
                .List<SomeEntity>();
    

    わかりましたが、"IntTable"とは何ですか ?これは、テーブル値の引数を渡すために作成されたSQLタイプの名前です。

    CREATE TYPE IntTable AS TABLE
    (
        ID INT
    );
    

    そしてsome_sp のようになります

    CREATE PROCEDURE some_sp
        @id IntTable READONLY,
        @par1 ...
    AS
    BEGIN
    ...
    END
    

    もちろん、これはSql Server 2008でのみ機能し、この特定の実装では、単一列のDataTable

    var dt = new DataTable();
    dt.Columns.Add("ID", typeof(int));
    

    これはPOCのみであり、完全なソリューションではありませんが、機能し、カスタマイズすると役立つ場合があります。誰かがより良い/より短い解決策を知っているなら、私たちに知らせてください。



    1. OracleSQLでGROUPBY句で列エイリアスを使用できないのはなぜですか。

    2. SQLite-CSVファイルからデータをインポートする

    3. 同じテーブルの列に外部キー制約を適用します

    4. SQLServer2014での遅延耐久性