2014-07-08 43 views
0

我遇到了一个奇怪的行为,我可以在一个简单的示例项目中缩小范围。TableAdapter总是为SQL Server 2008中的标量函数返回null

我试图从德国相应的Visual Studio的条款翻译成英文

的组件包括: - 的Visual Studio 2013点快速 - C# - MSSQL Server 2008 R2的 - .NET框架4.5 - 使用数据集和一个查询

该示例函数是非常简单的:

CREATE FUNCTION [dbo].[fTest] 
    ( ) 
    RETURNS INT 
    AS 
    BEGIN 
     RETURN 42 
    END 

然后我添加了一个DataSet,并通过TableAdapter配置助手使用“现有存储过程”将查询包含在默认设置中。 Visual Studio在上下文菜单上有一个“数据预览”功能。在那里,我将收到正确的结果值。

现在添加一些简单的代码:

using functionTest.DataSet1TableAdapters; 
    using System; 

    namespace functionTest 
    { 
     class Program 
     { 
      static void Main(string[] args) 
      { 
       QueriesTableAdapter qta = new QueriesTableAdapter(); 
       object result = qta.fTest(); 
       int? resI = (int?)result; 
       Console.WriteLine("result: " + resI); 
      } 
     } 
    } 

奇怪的结果永远是零。

编辑:

所生成的TableAdapter代码:

namespace functionTest.DataSet1TableAdapters { 


    /// <summary> 
    ///Represents the connection and commands used to retrieve and save data. 
    ///</summary> 
    [global::System.ComponentModel.DesignerCategoryAttribute("code")] 
    [global::System.ComponentModel.ToolboxItem(true)] 
    [global::System.ComponentModel.DataObjectAttribute(true)] 
    [global::System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.DataSource.Design.TableAdapterDesigner, Microsoft.VSDesigner" + 
     ", Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] 
    [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")] 
    public partial class QueriesTableAdapter : global::System.ComponentModel.Component { 

     private global::System.Data.IDbCommand[] _commandCollection; 

     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] 
     protected global::System.Data.IDbCommand[] CommandCollection { 
      get { 
       if ((this._commandCollection == null)) { 
        this.InitCommandCollection(); 
       } 
       return this._commandCollection; 
      } 
     } 

     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] 
     private void InitCommandCollection() { 
      this._commandCollection = new global::System.Data.IDbCommand[1]; 
      this._commandCollection[0] = new global::System.Data.SqlClient.SqlCommand(); 
      ((global::System.Data.SqlClient.SqlCommand)(this._commandCollection[0])).Connection = new global::System.Data.SqlClient.SqlConnection(global::functionTest.Properties.Settings.Default.connectionString); 
      ((global::System.Data.SqlClient.SqlCommand)(this._commandCollection[0])).CommandText = "dbo.fTest"; 
      ((global::System.Data.SqlClient.SqlCommand)(this._commandCollection[0])).CommandType = global::System.Data.CommandType.StoredProcedure; 
      ((global::System.Data.SqlClient.SqlCommand)(this._commandCollection[0])).Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@RETURN_VALUE", global::System.Data.SqlDbType.Int, 4, global::System.Data.ParameterDirection.ReturnValue, 10, 0, null, global::System.Data.DataRowVersion.Current, false, null, "", "", "")); 
     } 

     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] 
     [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")] 
     public virtual object fTest() { 
      global::System.Data.SqlClient.SqlCommand command = ((global::System.Data.SqlClient.SqlCommand)(this.CommandCollection[0])); 
      global::System.Data.ConnectionState previousConnectionState = command.Connection.State; 
      if (((command.Connection.State & global::System.Data.ConnectionState.Open) 
         != global::System.Data.ConnectionState.Open)) { 
       command.Connection.Open(); 
      } 
      object returnValue; 
      try { 
       returnValue = command.ExecuteScalar(); 
      } 
      finally { 
       if ((previousConnectionState == global::System.Data.ConnectionState.Closed)) { 
        command.Connection.Close(); 
       } 
      } 
      if (((returnValue == null) 
         || (returnValue.GetType() == typeof(global::System.DBNull)))) { 
       return null; 
      } 
      else { 
       return ((object)(returnValue)); 
      } 
     } 
    } 
} 

编辑: 另一个提示:内部CommandCollection包含有效的结果。我在调试器veried这一点,也暴露出CommandCollection和访问它:

IDataParameterCollection test = qta._commandCollection[0].Parameters; 
SqlParameter param = (SqlParameter) test[0]; 
int? res = (int?) param.Value; 
+0

您可以共享QueriesTableAdapter的源代码吗? – Darek

+0

当C#和SQL服务器之间的数据类型不匹配时,会发生这种情况。但是,在提供QueriesTableAdapter的源代码之后,我们可以提供具体的原因。 –

+0

试试这个,int? resI =(int?)result.ToString(); –

回答

0

看来,物体从标量值函数返回总是空使用command.executescalar()。

所以无法通过这种方式检索返回值。我认为这是一个MS问题,因为这当然是明显的做法。

甲解决办法是编辑生成的代码以上如下:

取代

returnValue = command.ExecuteScalar(); 

command.ExecuteScalar(); 
returnValue = command.Parameters["@RETURN_VALUE"].Value; 

。当然, “@RETURN_VALUE” 必须匹配指定的名称在你的表适配器中。

这对我有效...希望它有帮助。

如果您编辑生成的代码