Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Възможно ли е да се използва `SqlDbType.Structured` за предаване на параметри с таблица с стойност в NHibernate?

Първата ми идея ad hoc беше да внедря свой собствен 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...
}

Не се прилагат повече методи; a 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Трябва да изброите всички тригери в базата данни на SQL Server с име на таблица и схема на таблицата

  2. Обобщена таблица и конкатенирани колони

  3. JPA SQL Server Без диалектно съпоставяне за JDBC тип:-9

  4. Вмъкване на резултати от съхранена процедура във временна таблица

  5. Нов начин за копиране на файлове в SQL Server 2019