Недавно я столкнулся с той же проблемой. Однако мне удалось преодолеть эту проблему с помощью некоторых других логик (подробности приведены ниже), но я не мог понять причину, по которой findOneAndUpdate вставляет повторяющиеся записи в mongodb.
Вы можете преодолеть эту проблему, следуя логике.
Используйте findOne или findById вместо findOneAndUpdate , чтобы найти документ в вашей коллекции, а затем вручную обновить документ и запустить save () .
Вы можете иметь лучшую идею с этим фрагментом кода
return new Promise(function (resolve, reject) {
Model.findOne({
someCondition...
}, function (err, item) {
if (err) {
reject(err);
} else {
item.someArray.push({
someKeyValue...
});
item.save().then((result) => {
resolve(result)
}).catch((err) => {
reject(err)
});
}
}).catch((err) => {
reject(err)
});
});
Это не будет вставлять повторяющиеся элементы. Однако, если вы узнали причину дублирования, обязательно обновите эту ветку.
Добавьте параметр, используя ParameterDirection.ReturnValue
. Возвращаемое значение будет присутствовать в параметре после выполнения.
Кроме того, чтобы получить результат (или любой другой выходной параметр по этому вопросу) из ADO.NET, сначала необходимо просмотреть все возвращенные наборы результатов (или пропустить их с помощью NextResult)
Это означает, что если у вас есть процедура, определенная следующим образом:
CREATE PROC Test(@x INT OUT) AS
SELECT * From TestTable
SELECT @x = 1
И попробуйте сделать это:
SqlCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Test"
cmd.Parameters.Add("@x", SqlDbType.Int).Direction = ParameterDirection.Output;
cmd.Parameters.Add("@retval", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
cmd.Execute();
int? x = cmd.Parameters["@x"].Value is DBNull ? null : (int?)cmd.Parameters["@x"].Value;
Тогда x будет содержать нуль. Чтобы заставить его работать, вы должны выполнить процедуру, подобную следующей:
using (var rdr = cmd.ExecuteReader()) {
while (rdr.Read())
MaybeDoSomething;
}
int? x = cmd.Parameters["@x"].Value is DBNull ? null : (int?)cmd.Parameters["@x"].Value;
В последнем случае x будет содержать 1, как и ожидалось.
ExecuteScalar возвращает первый столбец первой строки. Поскольку вы больше не выбираете и не создаете набор результатов, поэтому он возвращал значение null. Так же, как к вашему сведению. Джон Сондерс имеет правильный ответ.
Просто несколько советов, но по умолчанию хранимая процедура возвращает 0, если не указано иное. По этой причине 0 часто используется для обозначения успеха, а ненулевые значения используются для указания условий возврата. Я бы согласился с предложением Джона или использовал бы выходной параметр
Если вы планируете использовать его, как в примере ниже, AccountExists может быть лучше в качестве функции.
В противном случае вы все равно сможете получить результат хранимой процедуры, вызвав ее из другой, выбрав результат.