Я пытаюсь уменьшить поле uint с 1 до 0. Из-за того, как работает Inc, мне нужно преобразовать его в int, как таковое:
UpdateDefinition<Student> updateDef = Builders<Student>.Update.Inc(s => (int)s.Grade, -1);
GetStudentCollection().UpdateOne(s => s.Id == 12345, updateDef);
Это отлично работает, когда я увеличиваю 1 вместо -1, но когда я запускаю этот код, я получаю следующую ошибку:
System.OverflowException: Value was either too large or too small for a UInt32.
at System.Convert.ToUInt32(Int32 value)
Я отладил полученный Student из этого запроса LINQ и подтвердил, что s.Grade был на 1, прежде чем я попытался уменьшить. Поскольку 0 находится в допустимом диапазоне uint, я не понимаю, почему он так ошибался.
Что я мог упустить и как я могу обойтись без кастинга uint? (Как в решении, кроме «не использовать uints»)
@AluanHaddad Потому что Inc требует этого. Он не принимает аргумент uint.





Inc в UpdateDefinitionBuilder определяется как:
public UpdateDefinition<TDocument> Inc<TField>(FieldDefinition<TDocument, TField> field, TField value);
Тот же тип TField используется для определения поля (FieldDefinition<TDocument, TField>) и для значения приращения, поэтому следующее выражение не будет компилироваться:
Builders<Student>.Update.Inc(x => x.Grade, -1);
Приведя x.Grade к int, вы можете обмануть компилятор, но не драйвер MongoDB. В конце концов драйвер попытается преобразовать значение -1 в тип модели uint, который выбрасывает OverflowException.
Если вы хотите сохранить тип данных uint для свойства Grade и иметь возможность его уменьшить, единственный способ, который я могу выяснить, - это обойти строго типизированный UpdateDefinition и использовать необработанный оператор $inc:
GetStudentCollection().UpdateOne(s => s.Id == 12345, "{ $inc: { Grade: -1 } }");
Зачем ты вообще кастинг?