代码之家  ›  专栏  ›  技术社区  ›  ejones

对于SQL Server 2008中的标量函数,TableAdapter始终返回null

  •  0
  • ejones  · 技术社区  · 11 年前

    我遇到了一个奇怪的行为,我可以在一个简单的示例项目中缩小范围。

    我正在尝试将相应的视觉工作室术语从德语翻译成英语

    组件包括: -Visual Studio 2013学习版 -C类# -MSSQL Server 2008 R2 -.NET Framework 4.5 -使用DataSet和查询

    示例函数非常简单:

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

    然后,我使用“现有存储过程”通过TableAdapter Configuration Assistant包含了一个DataSet和一个Query,并将其保留为默认设置。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包含有效结果。我在调试器中验证了这一点,并公开了CommandCollection并访问它:

    IDataParameterCollection test = qta._commandCollection[0].Parameters;
    SqlParameter param = (SqlParameter) test[0];
    int? res = (int?) param.Value;
    
    1 回复  |  直到 11 年前
        1
  •  0
  •   James Thorpe    11 年前

    使用command.executescalar(),从标量值函数返回的对象似乎总是空的。

    因此,无法以这种方式检索返回值。我认为这是一个MS问题,因为这是一种显而易见的方法。

    解决方法是按如下方式编辑上面生成的代码:

    代替

    returnValue = command.ExecuteScalar();
    

    具有

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

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

    这对我有用…希望能有所帮助。

    如果编辑生成的代码

    推荐文章