Da quando ho fatto un breve commento sulla tua domanda, ho avuto la possibilità di giocare completamente con le opzioni. Sembra che al momento (anche provando .NET 4.6 e SQL 2014) non sia possibile impostare SqlGeography
OPPURE SqlGeometry
come typeof()
parametro quando si definisce una colonna per una DataTable
. Per assoluta chiarezza, puoi farlo in .NET e persino popolarlo, ma non puoi quindi passare quella tabella come TVP a una stored procedure.
Ci sono due opzioni.
Opzione 1. Passa il valore in formato WKT.
Definisci il tipo di tabella come segue.
CREATE TYPE [dbo].[WKT_Example] AS TABLE
(
[geom] [varchar](max) NOT NULL
)
Quindi definisci la tua stored procedure come segue.
CREATE PROCEDURE [dbo].[BulkInsertFromWKT]
@rows [dbo].[WKT_Example] READONLY
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO [dbo].[Table1]
([SpatialData])
SELECT
geometry::STGeomFromText(R.[SpatialData], 4326)
FROM
@rows R;
END
Definisci il tuo DataTable .NET come segue:
DataTable wktTable = new DataTable();
wktTable.Columns.Add("SpatialData", typeof(string));
Compilalo come segue:
for (int j = 0; j < geometryCollection.Count; j++)
{
System.Data.SqlTypes.SqlString wkt = geometryCollection[j].STAsText().ToSqlString();
wktTable.Rows.Add(wkt.ToString());
}
Opzione 2. Passa il valore in formato WKB.
Definisci il tipo di tabella come segue.
CREATE TYPE [dbo].[WKB_Example] AS TABLE
(
[geom] [varbinary](max) NOT NULL
)
Quindi definisci la tua stored procedure come segue.
CREATE PROCEDURE [dbo].[BulkInsertFromWKB]
@rows [dbo].[WKB_Example] READONLY
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO [dbo].[Table1]
([SpatialData])
SELECT
geometry::STGeomFromWKB(R.[SpatialData], 4326)
FROM
@rows R;
END
Definisci il tuo DataTable .NET come segue:
DataTable wkbTable = new DataTable();
wkbTable.Columns.Add("SpatialData", typeof(System.Data.SqlTypes.SqlBytes));
Compilalo come segue:
for (int j = 0; j < geometryCollection.Count; j++)
{
wkbTable.Rows.Add(geographyCollection[j].STAsBinary());
}
Note:
Definisci il tuo SqlParameter come segue:
SqlParameter p = new SqlParameter("@rows", SqlDbType.Structured);
p.TypeName = "WKB_Example"; // The name of your table type
p.Value = wkbTable;
Ho lasciato un SRID di 4326 dal mio lavoro di geografia. Puoi cambiarlo come preferisci, e in effetti se stai usando Geography
Suggerirei di renderlo un secondo parametro per darti flessibilità.
Inoltre, se le prestazioni sono fondamentali, scoprirai che l'utilizzo di WKB è migliore. I miei test hanno rilevato che WKB è stato completato dal 45% al 65% del tempo impiegato da WKT. Questo varierà in base alla complessità dei tuoi dati e alla tua configurazione.
Le informazioni che hai trovato specificando il UdtTypeName
del parametro come "Geometria" / "Geografia" è corretto quando la procedura memorizzata ha un parametro di tipo [Geometria] o [Geografia]. Non si applica ai TVP.