【问题标题】:How to loop through list of complex type objects and pass to a method calling SQL Stored procedure如何遍历复杂类型对象列表并传递给调用 SQL 存储过程的方法
【发布时间】:2016-05-19 13:05:14
【问题描述】:

如何遍历对象列表以将所述对象传递给通过存储过程在 SQL db 中插入行的方法?

in this question 的帮助下,我做到了这一点:

namespace NA.Controllers
{
   public class NC : ApiController
   {
      [Route("AddNote")]
      [HttpPost]
    public HttpResponseMessage PostNote(List<Note> items)
    {
        //NoteJson deserializednote = JsonConvert.DeserializeObject<NoteJson>(item);
        //Note notesdata = new Note(item);
        NotesAccept.Models.INoteRepository Repository = new NotesAccept.Models.NoteDataRepository();
        foreach (Note item in items)
        {

        item = Repository.Add(item);

        }
        var response = Request.CreateResponse<List<Note>>(HttpStatusCode.OK, items);
        return response;
    }
   }
}

但现在我被困住了,因为 item= 现在是一个迭代变量,但我需要将它传递给一个方法:

namespace NA.Models
{
  class NoteDataRepository : INoteRepository
  {
     public void Add(Note item)
     {
        if (item == null)
        {
            throw new ArgumentNullException("item");
        }
        else
        {
            String strConnString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
            SqlConnection con = new SqlConnection(strConnString);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "BL_IntegrationInsertNote";
            cmd.Parameters.Add("@Client", SqlDbType.VarChar).Value = item.Client.Trim();
            cmd.Parameters.Add("@Case", SqlDbType.VarChar).Value = item.Case;
            cmd.Parameters.Add("@Text", SqlDbType.VarChar).Value = item.Text.Trim();
            cmd.Parameters.Add("@When", SqlDbType.DateTime).Value = item.Date;
            cmd.Parameters.Add("@Ext", SqlDbType.Bit).Value = item.Type;
            cmd.Parameters.Add("@return", SqlDbType.Int).Direction = ParameterDirection.Output;
            cmd.Connection = con;

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
                string id = cmd.Parameters["@return"].Value.ToString();
                string lblMessage = null;
                lblMessage = "Record inserted successfully. ID = " + id;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                con.Close();
                con.Dispose();
            }
        }    
        //return item;
    }

    IEnumerable<Note> INoteRepository.GetAll()
    {
        throw new NotImplementedException("getitems");
    }
}
}

我仍然是 C# 的新手,所以我不知道如何实现这一点,特别是因为整个解决方案仍然是来自整个网络的“复制和粘贴”,并且整个网络好奇地专注于循环遍历简单类型。复杂类型如何做到这一点?

正如其他问题所述,这是一个关乎职业生死的问题(我是数据库开发人员,不是 VS 大师,尤其是在两天两夜之后)。

【问题讨论】:

  • 我不明白你的问题,你不确定如何将item 传递给函数?也许您应该展示您尝试过的方法并告诉我们为什么它不起作用。
  • 在foreach循环中如果使用return response,只会处理第一个值。
  • @CodingGorilla item 是 Note() Data 类的一个实例,它被定义为我可以反序列化通过传入的 HTTPPost 请求接收到的 JSON 数组并将值存储在其中,这些值是存储过程的参数我正在调用粘贴的存储库。在添加 foreach 之前,我如上所述通过了项目。现在 Item 是迭代变量,但我仍然需要将它(或在添加 foreach() 之前包含的数据)传递给 Add(Note item)。
  • @VinayPandey 使用 return 传回添加行的 HTTP 请求 ID。再说一遍:这是在添加 foreach() 之前。您所看到的只是从各种“如何...”粘贴的代码,我几乎不明白。如何将 SQL 存储过程中的 OUTPUT 传回以响应 HTTP 请求?
  • 您正在做的事情被称为 RBAR“通过痛苦的行来行”。您需要研究“基于集合”的方法来插入多行。我知道你是个新手……但相信我,我希望在我还是个新手的时候有人抓住我并说“没有 RBAR”。虽然我不会使用 OPENXML,但本文讨论了这种方法。 tinyurl.com/h2uez8s 这是比 OPENXML 更好的方法 tinyurl.com/zxcrsp7

标签: c# arrays sql-server json foreach


【解决方案1】:
  1. 您仍然忘记将该 ID 从 DB 分配给项目。

  2. 你还有

    return item;
    

    在不返回任何内容的方法中(public void Add(Note item))。

    所以只需删除该返回行。

  3. 然后替换

    item = Repository.Add(item);
    

    只有

    Repository.Add(item);
    

【讨论】:

  • 对不起,从其他问题粘贴没有注释掉(已经完成)。无论如何,构建和发布的解决方案和测试返回:"Message":"An error has occurred.","ExceptionMessage":"Object reference not set to an instance of an object.","ExceptionType":"System.NullReferenceException","StackTrace":" at NotesAccept.Controllers.NotesController.PostNote(List``1 items)\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.&lt;&gt;c__DisplayClass10.&lt;GetExecutor&gt;b__9(Object instance, Object[] methodParameters)\r\n (...)
  • 所以请编辑您的帖子以反映您的最新版本 - 包括 PostNote 方法的更改。
  • 哪一行导致异常?如果您不知道,请尝试运行调试器,或者在其中放置一些日志以显示崩溃的位置。
  • 你也不希望这部分var response = Request.CreateResponse &lt; NotesAccept.Models.Note&gt;(HttpStatusCode.Created, item); return response;在foreach循环中,你只想在action方法结束时返回结果。
  • 是的,我之前实施了您的上述更正,但没有更新问题。急于测试和调试解决方案...现在尝试 - 但在远程服务器上调试部署的应用程序需要一段时间才能设置...
【解决方案2】:

你可以将它作为xml传递并在sql存储过程中迭代并进行批量插入,或者如果你使用的sql和.net版本支持它,你可以使用表数据类型。

【讨论】:

    【解决方案3】:

    在 foreach 循环中试试这个:

    var tempItem = item;
    tempItem = Repository.Add(tempItem);
    

    【讨论】:

    • 感谢您的建议。也许进展:Can't implicitly convert type void to NA.Models.Note
    猜你喜欢
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多