我撰寫了一個存盤程序,它采用我創建的兩種型別作為引數,稱為Type1和Type2:
CREATE TYPE Type1 AS TABLE
(
Id [int] NULL,
Value [float] NULL
)
CREATE TYPE Type2 AS TABLE
(
Id [int] NULL,
Name [varchar](20) NULL,
Value [float] NULL
)
CREATE PROCEDURE [SP-Name]
(@Id INT = 1,
@UserName VARCHAR(500) = 'test',
@Item1 Type1 READONLY,
@Item2 Type2 READONLY)
AS
BEGIN
SELECT *
FROM @Item1
END;
當我在 SQL Server 本身中呼叫這個存盤程序時,它運行沒有錯誤,但是我在 C# 中撰寫相同的代碼,我得到一個錯誤。問題是什么?
這就是我在 C# 中呼叫此存盤程序的方式:
ENTITIES.SqlQuery<Result>($"EXEC [SP-Name] @Item1",
new[] {
new SqlParameter
{
SqlDbType = SqlDbType.Structured,
TypeName = "Type1",
Value = listItems.ToDataTable(),//Get list Item from database and Convert to DATA-TABLE
ParameterName = "Item1"
}}).ToList();
public class Result
{
public int Id { get; set; }
public string Value { get; set; }
}
public static DataTable ToDataTable<T>(this List<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
// Get all the properties
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in Props)
{
// Defining type of data column gives proper data table
var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType);
// Setting column names as Property names
dataTable.Columns.Add(prop.Name, type);
}
foreach (T item in items)
{
var values = new object[Props.Length];
for (int i = 0; i < Props.Length; i )
{
// inserting property values to datatable rows
values[i] = Props[i].GetValue(item, null);
}
dataTable.Rows.Add(values);
}
// put a breakpoint here and check datatable
return dataTable;
}
這是我得到的錯誤:
運算元型別沖突:Item1 與 int 不兼容
uj5u.com熱心網友回復:
這里的問題是你認為因為你有一個名為的變數@Item1,SQL Server 將推斷它是用于 parameter @Item1,因為它們共享相同的名稱;這個假設是錯誤的。
當您省略要傳遞變數的引數時,變數(或文字)將根據序號位置傳遞給引數。您為引數傳遞一個值@Item1,該值將傳遞給您的第一個引數@Id。這就是您收到錯誤的原因。@Item1被定義為結構化資料型別 ( SqlDbType.Structured),但是@Id是int; 沒有相同的資料型別,你會得到一個錯誤。
如果要省略引數,請明確說明要傳遞的引數:
ENTITIES.SqlQuery<Result>($"EXEC dbo.[SP-Name] @Item1 = @Item1;",
或者,可能更好,只是從程序中洗掉所有其他引數,因為您不使用它們:
CREATE PROCEDURE dbo.[SP-Name] @Item1 Type1 READONLY
AS
BEGIN
SELECT *
FROM @Item1;
END;
然后你可以使用 use EXEC dbo.[SP-Name] @Item1;。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/426639.html
