Kể từ khi đưa ra một bình luận ngắn về câu hỏi của bạn, tôi đã có cơ hội xem xét đầy đủ các tùy chọn. Có vẻ như hiện tại (ngay cả khi thử .NET 4.6 và SQL 2014), bạn không thể đặt SqlGeography
HOẶC SqlGeometry
dưới dạng typeof()
khi xác định cột cho DataTable
. Để rõ ràng tuyệt đối, bạn có thể làm điều đó trong .NET và thậm chí điền nó, nhưng sau đó bạn không thể chuyển bảng đó dưới dạng TVP đến một Thủ tục được lưu trữ.
Có hai lựa chọn.
Tùy chọn 1. Chuyển giá trị ở định dạng WKT.
Xác định loại bảng của bạn như sau.
CREATE TYPE [dbo].[WKT_Example] AS TABLE
(
[geom] [varchar](max) NOT NULL
)
Sau đó, xác định Thủ tục đã lưu trữ của bạn như sau.
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
Xác định .NET DataTable của bạn như sau:
DataTable wktTable = new DataTable();
wktTable.Columns.Add("SpatialData", typeof(string));
Điền nó như sau:
for (int j = 0; j < geometryCollection.Count; j++)
{
System.Data.SqlTypes.SqlString wkt = geometryCollection[j].STAsText().ToSqlString();
wktTable.Rows.Add(wkt.ToString());
}
Tùy chọn 2. Chuyển giá trị ở định dạng WKB.
Xác định loại bảng của bạn như sau.
CREATE TYPE [dbo].[WKB_Example] AS TABLE
(
[geom] [varbinary](max) NOT NULL
)
Sau đó, xác định Thủ tục đã lưu trữ của bạn như sau.
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
Xác định .NET DataTable của bạn như sau:
DataTable wkbTable = new DataTable();
wkbTable.Columns.Add("SpatialData", typeof(System.Data.SqlTypes.SqlBytes));
Điền nó như sau:
for (int j = 0; j < geometryCollection.Count; j++)
{
wkbTable.Rows.Add(geographyCollection[j].STAsBinary());
}
Ghi chú:
Xác định SqlParameter của bạn như sau:
SqlParameter p = new SqlParameter("@rows", SqlDbType.Structured);
p.TypeName = "WKB_Example"; // The name of your table type
p.Value = wkbTable;
Tôi đã để lại SRID là 4326 từ công việc địa lý của mình. Bạn có thể thay đổi điều này thành bất cứ điều gì bạn muốn - và thực sự nếu bạn đang sử dụng Geography
Tôi khuyên bạn nên đặt nó làm tham số thứ hai để mang lại cho bạn sự linh hoạt.
Ngoài ra, nếu hiệu suất là quan trọng, bạn sẽ thấy sử dụng WKB tốt hơn. Các bài kiểm tra của tôi cho thấy WKB đã hoàn thành trong 45% đến 65% thời gian WKT thực hiện. Điều này sẽ thay đổi tùy theo độ phức tạp của dữ liệu và thiết lập của bạn.
Thông tin bạn tìm thấy khi chỉ định UdtTypeName
của tham số là "Hình học" / "Địa lý" là đúng khi Thủ tục đã lưu trữ của bạn có tham số thuộc loại [Hình học] hoặc [Địa lý]. Nó không áp dụng cho TVP.