Unterstützt Dapper SQL 2008 Table-Valued Parameters?

Weiß jemand, ob es möglich ist, tabellarische Parameterdaten an eine gespeicherte Prozedur mit Dapper zu übergeben?

   

    Es gibt jetzt (n Dapper 1.26 und höher) direkte Unterstützung für tabellwertige Parameter, die in Dapper gebackt werden. Da bei gespeicherten Prozeduren der Datentyp in die API “sproc” integriert ist, müssen Sie lediglich eine DataTable bereitstellen:

     var data = connection.Query(..., new { id=123, name="abc", values = someTable }, ...); 

    Für direkten Befehlstext haben Sie zwei andere Möglichkeiten:

    • Verwenden Sie eine Hilfsmethode, um dem benutzerdefinierten Datentyp mitzuteilen:

       var data = connection.Query(..., new { id=123, name="abc", values = someTable.AsTableValuedParameter("mytype") }, ...); 
    • teilen Sie der Datentabelle selbst mit, welcher benutzerdefinierte Datentyp verwendet werden soll:

       someTable.SetTypeName("mytype"); var data = connection.Query(..., new { id=123, name="abc", values = someTable }, ...); 

    Jeder von diesen sollte gut funktionieren.

    Ja, wir unterstützen sie, aber Sie müssen Ihre eigenen Helfer programmieren.

    Beispielsweise:

     class IntDynamicParam : Dapper.SqlMapper.IDynamicParameters { IEnumerable numbers; public IntDynamicParam(IEnumerable numbers) { this.numbers = numbers; } public void AddParameters(IDbCommand command) { var sqlCommand = (SqlCommand)command; sqlCommand.CommandType = CommandType.StoredProcedure; List number_list = new List(); // Create an SqlMetaData object that describes our table type. Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) }; foreach (int n in numbers) { // Create a new record, using the metadata array above. Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition); rec.SetInt32(0, n); // Set the value. number_list.Add(rec); // Add it to the list. } // Add the table parameter. var p = sqlCommand.Parameters.Add("@ints", SqlDbType.Structured); p.Direction = ParameterDirection.Input; p.TypeName = "int_list_type"; p.Value = number_list; } } // SQL Server specific test to demonstrate TVP public void TestTVP() { try { connection.Execute("CREATE TYPE int_list_type AS TABLE (n int NOT NULL PRIMARY KEY)"); connection.Execute("CREATE PROC get_ints @ints int_list_type READONLY AS select * from @ints"); var nums = connection.Query("get_ints", new IntDynamicParam(new int[] { 1, 2, 3 })).ToList(); nums[0].IsEqualTo(1); nums[1].IsEqualTo(2); nums[2].IsEqualTo(3); nums.Count.IsEqualTo(3); connection.Execute("DROP PROC get_ints"); connection.Execute("DROP TYPE int_list_type"); } } 

    Stellen Sie sicher, dass Sie die performance für Tabellenwerte richtig testen. Als ich dies für das Übergeben von int-Listen getestet habe, war es signifikant langsamer als das Weitergeben von mehreren params.

    Ich bin absolut nicht dagegen, einige SQL Server-spezifische Helfer für dapper im contrib-Projekt zu haben, aber der Core-Dapper vermeidet, wenn möglich, herstellerspezifische Tricks hinzuzufügen.

    Ich weiß, dass dieses Ticket ALT ist, sehr alt, aber ich wollte Sie wissen lassen, dass ich das Dapper.Microsoft.Sql-Paket veröffentlicht habe, das generische TVPs unterstützt.

    https://www.nuget.org/packages/Dapper.Microsoft.Sql/

    Probe verwenden:

     List nums = this.connection.Query( "get_ints", new TableValuedParameter( "@ints", "int_list_Type", new[] { 'A', 'B', 'C' })).ToList(); 

    Es basiert auf den originalen classn von Dapper Testprojekt.

    Genießen!

    Heute ist es nicht. Wir haben tatsächlich Table-Valed-Parameter für unsere freche In-Implementierung untersucht ( where col in @values ), waren aber von der Performance sehr unbeeindruckt. Im Zusammenhang mit einem SPROC ist dies jedoch sinnvoll.

    Am besten protokollieren Sie dies als Problem auf der Projektwebsite, damit wir sie verfolgen / priorisieren können. Es klingt, als wäre etwas machbar, wahrscheinlich ähnlich zu den Optionen DbString oder DynamicParameters.

    Aber heute? Nein.