Подтвердить что ты не робот

Лучшая аннотация данных для десятичной (18,2)

У меня есть столбец внутри моего SQL Server 2008 с типом Decimal(18,2). Но на основе сущности, какова лучшая проверка аннотации данных, которую я могу применить к этому свойству, внутри моего веб-приложения asp.net MVC?

4b9b3361

Ответ 1

Нет явной аннотации данных для десятичной дроби, поэтому вам нужно использовать два отдельных для добавления ограничений.

Две десятичные точки

[RegularExpression(@"^\d+\.\d{0,2}$")]

Это регулярное выражение будет гарантировать, что свойство имеет не более двух десятичных знаков.

Максимум 18 цифр

[Range(0, 9999999999999999.99)]

Предполагая, что вы не принимаете никаких отрицательных чисел. В противном случае замените 0 на -9999999999999999.99.

Результат

[RegularExpression(@"^\d+\.\d{0,2}$")]
[Range(0, 9999999999999999.99)]
public decimal Property { get; set; }

Ответ 2

Я думаю, что ответ @jumpingcode можно объединить в один RegularExpressionAttribute.

[RegularExpression(@"^(0|-?\d{0,16}(\.\d{0,2})?)$")]
public decimal Property
{
    get;
    set;
}

Это может использоваться для любых precision и scale. 16 заменяется на precision - scale, а 2 заменяется на scale. Регулярное выражение должно соответствовать номерам, введенным как ###, 0.##, .##, 0 и ###.##, а также отрицательные значения.

Ответ 3

Кажется, это правильный ответ (приведенные выше ответы ограничивают допустимые числа, которые могут быть вставлены в тип данных Decimal (18,2) или вызывать ошибки компиляции, если вы применяете их к вашему коду - пожалуйста, подтвердите сами ):

Используйте следующие два ограничения вместе:

Две десятичные точки

[RegularExpression(@"^\d+.?\d{0,2}$", ErrorMessage = "Invalid Target Price; Maximum Two Decimal Points.")]

Максимум 18 цифр

  [Range(0, 9999999999999999.99, ErrorMessage = "Invalid Target Price; Max 18 digits")]

Ответ 4

Для другого подхода, который некоторые могут считать более читаемым, вы можете переопределить метод OnModelCreating вашего DbContext для установки точности, например:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

           modelBuilder.Entity<YourEntity>()
                    .Property(x => x.TheProprty)
                    .HasPrecision(18, 2);
    }

Преимущество: строго типизированное vs пользовательское регулярное выражение

Недостаток: не вижу его в классе с помощью всего лишь сканирования

Ответ 5

Следуя примеру @Schmalls (и комментируя его преобразование в атрибут), я создал рабочий пример (использует интерполяцию строк С# 6):

public class PrecisionAndScaleAttribute : RegularExpressionAttribute
{
    public PrecisionAndScaleAttribute(int precision, int scale) : base([email protected]"^(0|-?\d{{0,{precision - scale}}}(\.\d{{0,{scale}}})?)$")
    {

    }
}

Использование:

[PrecisionAndScale(6, 2, ErrorMessage = "Total Cost must not exceed $9999.99")]
public decimal TotalCost { get; set; }

Ответ 6

 [Range(1,(double) decimal.MaxValue, ErrorMessage="value should be between{1} and {2}."]

Ответ 7

Я использую почти эксклюзивно (б/с это просто и работает)

[Range(typeof(decimal), "0", "1")]
public decimal Split { get; set; }

Затем, если мне нужно конвертировать обратно в двойной, я добавляю конверсию

(double)model.Split

Ответ 8

Если вы напишите аннотацию 'column', все будет работать нормально

    [Required]
    [Column(TypeName = "decimal(18, 6)")]
    public decimal Foo { get; set; }