Let me explain my situation in full.
I have a JavaScript object like
[{"QuestionId":"1","AnswerId":"21","AnswerText":"34"},
{"QuestionId":"2","AnswerId":"22","AnswerText":"23"},...]
which I need to use to either insert or update rows of a T-SQL table generated by
CREATE TABLE Answers (
id INT IDENTITY (1,1),
question_id INT NOT NULL,
partner_id UNIQUEIDENTIFIER NOT NULL,
val INT,
PRIMARY KEY (id),
FOREIGN KEY (question_id) REFERENCES Questions(id),
FOREIGN KEY (partner_id) REFERENCES Partners(id)
);
The AJAX call is
var QAs = new Array();
$('.completeness.for-answer').each(function () {
QAs.push({
QuestionId : $(this).attr('data-qstnid'),
AnswerId : $(this).attr('data-answid'),
AnswerText : $(this).val(),
});
});
console.log(JSON.stringify(QAs));//TEST
$.ajax({
method: 'POST',
url: '/Answers/SubmitAnswers',
data : QAs,
success: function (retobj) {
console.log(retobj);
},
error: function () {
console.log("Error ...");
}
});
Each item in the list of updates, when it is transmitted to the database in the form of executing a stored procedure
CREATE PROCEDURE AddOrUpdateAnswer
@AnswerId INT,
@AnswerVal INT,
@QuestionId INT,
@PartnerId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
IF EXISTS ( SELECT 1 FROM Answers WHERE id=@AnswerId )
UPDATE Answers SET val=@AnswerVal WHERE id=@AnswerId
ELSE
INSERT INTO Answers (question_id, partner_id, val) VALUES (@QuestionId, @PartnerId, @AnswerVal)
END
The reason for the condition is because the input will be in 1 of 2 forms:
@AnswerIdwill beNULL(the input corresponds to an answer that has not yet been submitted) and the other values will be defined. The other values are needed to@AnswerIdwill be non-NULLand the other values will be defined although@PartnerIdand@QuestionIdare irrelevant for the update because that information is already within the table relations.
First question: Is that sproc the most efficient way of doing an "Add or Update"? Is it possible to do an "Add or Update" that brings in all the items at once? Because, you see, I'm calling this on each item.
The controller I'm using to handle the AJAX request that passes in the JavaScript object is
[HttpPost]
public ActionResult SubmitAnswers ( List<AnswerSubmission> Answers )
{
bool goodSoFar = true;
string status = "Answers submitted successfully";
try
{
this._Db.SubmitAnswers(Answers, this._Pid);
}
catch ( Exception e )
{
goodSoFar = false;
status = String.Format("Exception occured during answer submission: {0}", e.Message);
}
return Json(new { Succeeded = goodSoFar, Message = status } );
}
where AnswerSubmission is defined by
public class AnswerSubmission
{
public int? AnswerId { get; set; }
public int? AnswerVal { get; set; }
public int QuestionId { get; set; }
}
The function SubmitAnswers looks like
public void SubmitAnswers ( List<AnswerSubmission> Answers, Guid PartnerId )
{
try
{
foreach ( AnswerSubmission A in Answers )
{
using ( SqlCommand cmd = new SqlCommand("AddOrUpdateAnswer", this._Conn) )
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@AnswerId", A.AnswerId);
cmd.Parameters.AddWithValue("@AnswerVal", A.AnswerVal);
cmd.Parameters.AddWithValue("@QuestionId", A.QuestionId);
cmd.Parameters.AddWithValue("@PartnerId", PartnerId);
this._Conn.Open();
cmd.ExecuteNonQuery();
this._Conn.Close();
}
}
} catch ( Exception ) { throw; }
}
Second question: Is that the correct way, with an Opening and then Closeing of the connection for each item? That seems like it would be inefficient. Is there a better way?
Third question: How do I debug an AJAX method like this? I've set up breakpoints all over the place in my controller, but none of them are getting hit. The exception that is getting thrown, which I see in the object returned by the success function of my JavaScript, says
"Exception occured during answer submission: Object reference not set to an instance of an object."
but doesn't point me to any line in my code. So I have no idea which object reference is not set to an instance of an object.
Any help greatly appreciated here.