Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数据库名称不允许与表值参数一起使用_C#_Asp.net_Sql_Sql Server 2008_Enterprise Library - Fatal编程技术网

C# 数据库名称不允许与表值参数一起使用

C# 数据库名称不允许与表值参数一起使用,c#,asp.net,sql,sql-server-2008,enterprise-library,C#,Asp.net,Sql,Sql Server 2008,Enterprise Library,调用Select函数时出现以下错误: 传入的表格数据流(TDS)远程过程调用(RPC) 协议流不正确。表值参数3 (“@SearchTableVar”),第0行第0列:数据类型0xF3(用户定义 表类型)指定了非零长度的数据库名称。数据库 名称不能与表值参数一起使用,只能与架构名称一起使用 和类型名称都是有效的 C#代码 //DTO public class SP_SearchEntity_Result { public string ID { get; set; } publi

调用
Select
函数时出现以下错误:

传入的表格数据流(TDS)远程过程调用(RPC) 协议流不正确。表值参数3 (“@SearchTableVar”),第0行第0列:数据类型0xF3(用户定义 表类型)指定了非零长度的数据库名称。数据库 名称不能与表值参数一起使用,只能与架构名称一起使用 和类型名称都是有效的

C#代码

//DTO
public class SP_SearchEntity_Result
{
    public string ID { get; set; }
    public string NAME { get; set; }
}

//Businesslogic
public IQueryable Select(int PageIndex, int PageSize, List<KeyValuePair<string, string>> SearchBy, List<KeyValuePair<string, System.Data.SqlClient.SortOrder>> SortBy)
{
    SqlDatabase obj = (SqlDatabase)DatabaseFactory.CreateDatabase();//System.Configuration.ConfigurationManager.ConnectionStrings["MySqlServer"].ConnectionString
    return obj.ExecuteSprocAccessor<SP_SearchEntity_Result>("SP_SearchEntity", PageIndex, PageSize, SearchBy.ToDataTable(), SortBy.ToDataTable()).AsQueryable<SP_SearchEntity_Result>();
}

//Extension methods
public static DataTable ToDataTable(this List<KeyValuePair<string, string>> source)
{
    DataTable dataTable = new DataTable("Test");
    dataTable.Columns.Add("KEY",typeof(System.String));
    dataTable.Columns.Add("VALUE", typeof(System.String));

    foreach (KeyValuePair<string, string> data in source)
    {
        var dr = dataTable.NewRow();
        dr["KEY"] = data.Key;
        dr["VALUE"] = data.Value;
        dataTable.Rows.Add(dr);
    }

    return dataTable;
}

public static DataTable ToDataTable(this List<KeyValuePair<string, System.Data.SqlClient.SortOrder>> source)
{
    DataTable dataTable = new DataTable("Test");
    dataTable.Columns.Add("KEY", typeof(System.String));
    dataTable.Columns.Add("VALUE", typeof(System.String));

    foreach (KeyValuePair<string, System.Data.SqlClient.SortOrder> data in source)
    {
        var dr = dataTable.NewRow();
        dr["KEY"] = data.Key;
        dr["VALUE"] = data.Value == System.Data.SqlClient.SortOrder.Ascending ? "ASC" : "DESC";
        dataTable.Rows.Add(dr);
    }

    return dataTable;
}

向传递表值参数有许多要求/限制。例如,请参见“将表值参数传递给存储过程”下的示例:

然后,代码定义一个
SqlCommand
,将
CommandType
属性设置为
StoredProcedure
。使用
AddWithValue
方法填充
SqlParameter
,并将
SqlDbType
设置为
Structured

请注意,仅使用
AddWithValue
是不够的-必须将
SqlDbType
更改为
Structured

我认为
executesprocacessor
方法没有执行此更改(或者,可能与其他一些示例一样,
TypeName
必须设置为表类型的名称)。我无法在企业库源代码中完整地阐述这一点,但由于我在解决方案中的任何地方都找不到“结构化”一词,因此我得出了这个结论


因此,如果您想使用TVPs,我认为您必须放弃企业库,自己使用
SqlClient
类型编写数据访问代码。(由于您使用的是TVPs,您已经放弃了切换到其他RDBMS的可能性)。

我发现存储过程参数的xml数据类型更易于使用。对于以下示例,您可以将参数转换为XML,而不是将其转换为DataTables:

CREATE PROCEDURE SP_SearchEntity
@PageIndex INT=NULL,      
@PageSize INT=NULL,     
@SearchTableVar xml=NULL,
@SortTableVar xml=NULL
AS
BEGIN
    /*Bla bla bla*/
    SELECT '1' as [ID], 'Nitin' as [NAME]
    SELECT '1' as [COUNT]
END
以下是将KeyValuePair序列化为XML后的一个示例和一个查询:

declare @sampleXml xml = '
<ArrayOfKeyValuePairOfstringstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
  <KeyValuePairOfstringstring>
    <key>foo</key>
    <value>bar</value>
  </KeyValuePairOfstringstring>
  <KeyValuePairOfstringstring>
    <key>hello</key>
    <value>world</value>
  </KeyValuePairOfstringstring>
</ArrayOfKeyValuePairOfstringstring>'

select
        Node.Elem.value('*:key[1]', 'nvarchar(800)') as [Key]
        ,Node.Elem.value('*:value[1]', 'nvarchar(800)') as Value
    from @sampleXml.nodes(N'/*:ArrayOfKeyValuePairOfstringstring/*:KeyValuePairOfstringstring') Node(Elem)
go
最后,您需要连接到数据库以获取结果集:

/// <summary>
/// Executes a SqlCommand that expects four result sets and binds the results to the given models
/// </summary>
/// <typeparam name="T1">Type: the type of object for the first result set</typeparam>
/// <typeparam name="T2">Type: the type of object for the second result set</typeparam>
/// <returns>List of Type T: the results in a collection</returns>
public void ExecuteAs<T1, T2>(SqlCommand command, List<T1> output1, List<T2> output2)
{
    string _modelName1 = typeof(T1).Name;
    string _modelName2 = typeof(T2).Name;
    string _commandText = command.CommandText;

    using (SqlConnection connection = GetOpenConnection())
    {
        using (command)
        {
            command.Connection = connection;
            command.CommandTimeout = _defaultCommandTimeout;
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())                                               // Call Read before accessing data.
                {
                    ReadAs<T1>(reader, _modelName1, output1, _commandText);
                }

                reader.NextResult();

                while (reader.Read())                                               // Call Read before accessing data.
                {
                    ReadAs<T2>(reader, _modelName2, output2, _commandText);
                }
            } // end using reader
        } // end using command
    } // end using connection
}   
//
///执行一个SqlCommand,该命令需要四个结果集,并将结果绑定到给定的模型
/// 
///类型:第一个结果集的对象类型
///类型:第二个结果集的对象类型
///类型T的列表:集合中的结果
public void ExecuteAs(SqlCommand命令、List output1、List output2)
{
字符串_modelName1=typeof(T1).Name;
字符串_modelName2=typeof(T2).Name;
字符串_commandText=command.commandText;
使用(SqlConnection=GetOpenConnection())
{
使用(命令)
{
command.Connection=连接;
command.CommandTimeout=\u defaultCommandTimeout;
使用(SqlDataReader=command.ExecuteReader())
{
while(reader.Read())//在访问数据之前调用Read。
{
ReadAs(reader,_modelName1,output1,_commandText);
}
reader.NextResult();
while(reader.Read())//在访问数据之前调用Read。
{
ReadAs(reader,_modelName2,output2,_commandText);
}
}//结束使用读卡器
}//结束使用命令
}//结束使用连接
}   
然后,您的选择方法看起来更像这样:

public void SelectInto<SP_SearchEntity_Result, int>(int PageIndex, int PageSize, List<KeyValuePair<string, string>> SearchBy, List<KeyValuePair<string, System.Data.SqlClient.SortOrder>> SortBy, List<<SP_SearchEntity_Result> result1, List<int> result2)
{
    SqlCommand command = new SqlCommand("SP_SearchEntity");
    command.CommandType = System.Data.CommandType.StoredProcedure;
    command.Parameters.Add("PageIndex", SqlDbType.Int).Value = PageIndex;
    command.Parameters.Add("SearchTableVar", SqlDbType.Xml).Value = SearchBy.ToXml();

    List<KeyValuePair<string, string>> SortByCastToString = // modify your ToDataTable method so you can pass a List<KeyValuePair<string, string>> for SortBy
    command.Parameters.Add("SortTableVar", SqlDbType.Xml).Value = SortByCastToString.ToXml();

    ExecuteAs<SP_SearchEntity_Result, int>(command, result1, result2); 
}

public void SomeCallingMethod()
{
    List<SP_SearchEntity_Result> _results = new List<SP_SearchEntity_Result>{};
    List<int> _counts = new List<int>{};
    // ...
    // setup your SearchBy and SortBy
    // ...

    SelectInto<SP_SearchEntity_Result, int>(1, 20, SearchBy, SortBy, _results, _counts);
}
public static DataSet SomeHelperMethod(DataTable tvp1, DataTable tvp2)
{
    DbCommand cmd = <SqlDatabase>.GetStoredProcCommand("StoredProcName");

    SqlParameter p1 = new SqlParameter("@p1", tvp1);
    p1.SqlDbType = SqlDbType.Structured;
    cmd.Parameters.Add(p1);

    SqlParameter p2= new SqlParameter("@p2", tvp2);
    p2.SqlDbType = SqlDbType.Structured;
    cmd.Parameters.Add(p2);

    return <SqlDatabase>.ExecuteDataSet(cmd);
}

public void SelectInto(int-PageIndex,int-PageSize,List-SearchBy,List-SortBy,ListTVPs)作为存储过程的参数,使用企业库数据访问应用程序块v6.0.1304对我来说很好。我的C代码如下所示:

public void SelectInto<SP_SearchEntity_Result, int>(int PageIndex, int PageSize, List<KeyValuePair<string, string>> SearchBy, List<KeyValuePair<string, System.Data.SqlClient.SortOrder>> SortBy, List<<SP_SearchEntity_Result> result1, List<int> result2)
{
    SqlCommand command = new SqlCommand("SP_SearchEntity");
    command.CommandType = System.Data.CommandType.StoredProcedure;
    command.Parameters.Add("PageIndex", SqlDbType.Int).Value = PageIndex;
    command.Parameters.Add("SearchTableVar", SqlDbType.Xml).Value = SearchBy.ToXml();

    List<KeyValuePair<string, string>> SortByCastToString = // modify your ToDataTable method so you can pass a List<KeyValuePair<string, string>> for SortBy
    command.Parameters.Add("SortTableVar", SqlDbType.Xml).Value = SortByCastToString.ToXml();

    ExecuteAs<SP_SearchEntity_Result, int>(command, result1, result2); 
}

public void SomeCallingMethod()
{
    List<SP_SearchEntity_Result> _results = new List<SP_SearchEntity_Result>{};
    List<int> _counts = new List<int>{};
    // ...
    // setup your SearchBy and SortBy
    // ...

    SelectInto<SP_SearchEntity_Result, int>(1, 20, SearchBy, SortBy, _results, _counts);
}
public static DataSet SomeHelperMethod(DataTable tvp1, DataTable tvp2)
{
    DbCommand cmd = <SqlDatabase>.GetStoredProcCommand("StoredProcName");

    SqlParameter p1 = new SqlParameter("@p1", tvp1);
    p1.SqlDbType = SqlDbType.Structured;
    cmd.Parameters.Add(p1);

    SqlParameter p2= new SqlParameter("@p2", tvp2);
    p2.SqlDbType = SqlDbType.Structured;
    cmd.Parameters.Add(p2);

    return <SqlDatabase>.ExecuteDataSet(cmd);
}
公共静态数据集SomeHelperMethod(数据表tvp1、数据表tvp2)
{
DbCommand cmd=.GetStoredProcCommand(“StoredProcName”);
SqlParameter p1=新的SqlParameter(“@p1”,tvp1);
p1.SqlDbType=SqlDbType.Structured;
cmd.Parameters.Add(p1);
SqlParameter p2=新的SqlParameter(“@p2”,tvp2);
p2.SqlDbType=SqlDbType.Structured;
cmd.Parameters.Add(p2);
return.ExecuteDataSet(cmd);
}

什么是
ToDataTable()
?这是扩展方法,问题已更新。您可能需要重新考虑您的进程名称。这是一个有趣的阅读。您能告诉我如何将存储过程的两个输出处理为对象吗?
public SqlConnection GetOpenConnection()
{
    _sqlConnection = new SqlConnection(_dbConnectionString); 
    _sqlConnection.Open();
    return _sqlConnection;
}
/// <summary>
/// Executes a SqlCommand that expects four result sets and binds the results to the given models
/// </summary>
/// <typeparam name="T1">Type: the type of object for the first result set</typeparam>
/// <typeparam name="T2">Type: the type of object for the second result set</typeparam>
/// <returns>List of Type T: the results in a collection</returns>
public void ExecuteAs<T1, T2>(SqlCommand command, List<T1> output1, List<T2> output2)
{
    string _modelName1 = typeof(T1).Name;
    string _modelName2 = typeof(T2).Name;
    string _commandText = command.CommandText;

    using (SqlConnection connection = GetOpenConnection())
    {
        using (command)
        {
            command.Connection = connection;
            command.CommandTimeout = _defaultCommandTimeout;
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())                                               // Call Read before accessing data.
                {
                    ReadAs<T1>(reader, _modelName1, output1, _commandText);
                }

                reader.NextResult();

                while (reader.Read())                                               // Call Read before accessing data.
                {
                    ReadAs<T2>(reader, _modelName2, output2, _commandText);
                }
            } // end using reader
        } // end using command
    } // end using connection
}   
public void SelectInto<SP_SearchEntity_Result, int>(int PageIndex, int PageSize, List<KeyValuePair<string, string>> SearchBy, List<KeyValuePair<string, System.Data.SqlClient.SortOrder>> SortBy, List<<SP_SearchEntity_Result> result1, List<int> result2)
{
    SqlCommand command = new SqlCommand("SP_SearchEntity");
    command.CommandType = System.Data.CommandType.StoredProcedure;
    command.Parameters.Add("PageIndex", SqlDbType.Int).Value = PageIndex;
    command.Parameters.Add("SearchTableVar", SqlDbType.Xml).Value = SearchBy.ToXml();

    List<KeyValuePair<string, string>> SortByCastToString = // modify your ToDataTable method so you can pass a List<KeyValuePair<string, string>> for SortBy
    command.Parameters.Add("SortTableVar", SqlDbType.Xml).Value = SortByCastToString.ToXml();

    ExecuteAs<SP_SearchEntity_Result, int>(command, result1, result2); 
}

public void SomeCallingMethod()
{
    List<SP_SearchEntity_Result> _results = new List<SP_SearchEntity_Result>{};
    List<int> _counts = new List<int>{};
    // ...
    // setup your SearchBy and SortBy
    // ...

    SelectInto<SP_SearchEntity_Result, int>(1, 20, SearchBy, SortBy, _results, _counts);
}
public static DataSet SomeHelperMethod(DataTable tvp1, DataTable tvp2)
{
    DbCommand cmd = <SqlDatabase>.GetStoredProcCommand("StoredProcName");

    SqlParameter p1 = new SqlParameter("@p1", tvp1);
    p1.SqlDbType = SqlDbType.Structured;
    cmd.Parameters.Add(p1);

    SqlParameter p2= new SqlParameter("@p2", tvp2);
    p2.SqlDbType = SqlDbType.Structured;
    cmd.Parameters.Add(p2);

    return <SqlDatabase>.ExecuteDataSet(cmd);
}