将GUID传递到存储过程方法C#

时间:2020-06-26 13:57:10

标签: c# sql sql-server stored-procedures

我基本上是C#的新手,所以我在这里寻求一些指导。我正在测试一种方法,我需要将guid列表传递给它并运行一个存储过程,该过程将基于传递给它的guid返回值,然后可以将其打印到控制台。当我仅通过一个GUID时,我可以使该方法起作用,但是当我通过GUID列表时,它似乎不起作用。

我觉得我在这里应该如何通过引导列表并返回它方面缺乏了解。我在尝试返回列表时遇到转换错误。

这是我走了多远,但我觉得自己现在被困住了,无法从网上找到的任何信息中获取任何进步。

class Program
{
    static void Main(string[] args)
    {
        List<Guid> tempguid = new List<Guid>();
        tempguid.Add(Guid.Parse("472USFA0-B705-9A73-ABD4-3B1870AF1409"));
        tempguid.Add(Guid.Parse("FA97E6BB-0875-5UB9-967A-87ECC396F9F0"));

        GetValue(tempguid);
        Console.WriteLine(GetValue);
    }

    public void GetValue(List<Guid> tempguid)
    {
        using (SqlConnection conn = new SqlConnection("connection string here"))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand("stored procedure here", conn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add(new SqlParameter("@id", tempguid));

            using (SqlDataReader rdr = cmd.ExecuteReader())
            {
                while (rdr.Read())
                {
                    Console.WriteLine((string)rdr["value"]);
                }
                Console.ReadLine();
            }
        }
    }
}

我应该像这样通过GetValue(List tempguid)传递列表吗?

编辑

好的,如果我使用TVP。

类似的东西:

CREATE TYPE [dbo].[Identity] AS TABLE(

[Id] [uniqueidentifier] NOT NULL
)
GO

然后我的过程将类似于:

CREATE OR ALTER PROCEDURE [dbo].[procedure_name]
@id dbo.Identity READONLY
as
SELECT t.[id]
      ,t.[value]
  FROM [dbo].[table1] t
  Inner Join @id i on i.Id = t.id

如何在c#中使用此TVP进行存储过程?

3 个答案:

答案 0 :(得分:1)

您需要在GUID列表上有一个foreach循环。试试:

foreach (var g in tempguid)
{
    cmd.Parameters.Add(new SqlParameter("@id", g));
    using (SqlDataReader rdr = cmd.ExecuteReader())
    {
       while (rdr.Read())
       {
          Console.WriteLine((string)rdr["value"]);
       }
       Console.ReadLine();
    }
    cmd.Parameteres.Clear();
}

答案 1 :(得分:0)

您无法将列表传递给sp。您需要将引导转换为csv字符串示例:

var param = string.Join(", ", tempguid);

然后

cmd.Parameters.Add(new SqlParameter("@id", param));

然后在sp上收到您的参数后,将其传递到String_Split中。祝你好运!

答案 2 :(得分:0)

从ADO .NET向TVPs传递值非常简单,与将数据传递给常规参数相比,它只需要很少的额外代码。

  • 对于数据类型,请指定SqlDbType.Structured。
  • 您可以在参数的TypeName属性中指定表类型的名称。
  • 您将参数的Value属性设置为合适的值。

如上面的链接所述,System.Data.SqlClient支持从DataTableDbDataReaderIEnumerable<T> \ SqlDataRecord对象中填充表值参数。

如果您的案例tempguid中已经有来自其他来源的Guid列表,则可以使用datatable将详细信息传递给存储过程。

DataTable tvp = new DataTable();
tvp.Columns.Add(new DataColumn("Id", typeof(Guid)));

// populate DataTable from your List here
foreach (var id in tempguid)
   tvp.Rows.Add(id);

并按如下所示更改ADO.NET代码-

conn.Open();
SqlCommand cmd = new SqlCommand("dbo.tvpProcedure", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvpParameter = new SqlParameter();
tvpParameter.ParameterName = "@id";
tvpParameter.SqlDbType = System.Data.SqlDbType.Structured;
tvpParameter.Value = tvp;
tvpParameter.TypeName = "dbo.testTVP";
cmd.Parameters.Add(tvpParameter);

 using (SqlDataReader rdr = cmd.ExecuteReader())
   {
     while (rdr.Read())
      {
        Console.WriteLine((string)rdr["value"]);
      }
       Console.ReadLine();
    }

旁注:

  • 您在代码中显示的GUIDs看起来无效,因为它们包含非 十六进制值。

    472USFA0-B705-9A73-ABD4-3B1870AF1409
       ^^
    FA97E6BB-0875-5UB9-967A-87ECC396F9F0
                   ^
    
  • 在我使用的情况下,将类型名称更改为有意义的代替dbo.Identity dbo.testTVP

其他信息-

http://www.sommarskog.se/arrays-in-sql-2008.html