मेरा पहला, तदर्थ, विचार मेरे अपने 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));
यह केवल पीओसी है, पूर्ण समाधान नहीं है, लेकिन यह काम करता है और अनुकूलित होने पर उपयोगी हो सकता है। अगर कोई बेहतर/छोटा समाधान जानता है तो हमें बताएं।