web-dev-qa-db-fra.com

Meilleure annotation de données pour une décimale (18,2)

J'ai une colonne à l'intérieur de mon serveur SQL 2008 avec le type de Decimal(18,2). Mais dans le cadre d'une entité, quelle est la meilleure validation d'annotation de données que je puisse appliquer à cette propriété dans mon application Web asp.net MVC? 

34
John John

Il n'y a pas d'annotation de données explicite pour une décimale, vous devez donc en utiliser deux distinctes pour ajouter des contraintes.

Deux points décimaux

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

Cette expression régulière garantira que la propriété a au plus deux décimales.

Max 18 chiffres

[Range(0, 9999999999999999.99)]

En supposant que vous n'acceptez aucun nombre négatif. Sinon, remplacez 0 par -9999999999999999.99.

Résultat

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

Je pense que la réponse de @ jumpingcode peut être combinée en une RegularExpressionAttribute.

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

Ceci peut être utilisé pour toutes les variables precision et scale. Le 16 est remplacé par precision - scale et le 2 est remplacé par le scale. L'expression régulière doit correspondre aux nombres entrés tels que ###, 0.##, .##, 0 et ###.## ainsi que des valeurs négatives.

13
Schmalls

Cela semble être la bonne réponse (les réponses ci-dessus restreignent les nombres valides pouvant être insérés dans un type de données Decimal (18,2) ou provoquent des erreurs de compilation en les appliquant à votre code - veuillez confirmer vous-même): 

Utilisez les deux contraintes suivantes ensemble:

Deux décimales

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

Max 18 chiffres

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

Pour une approche différente que certains pourraient considérer plus lisible, vous pouvez remplacer la méthode OnModelCreating de votre DbContext pour définir la précision, comme suit:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

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

Avantage: expression régulière fortement typée vs personnalisée

Inconvénient: impossible de le voir dans la classe avec juste un scan

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

Suite à l’exemple de @Schmalls (et à son commentaire en tant qu’attribut), j’ai créé un exemple de travail (utilise l’interpolation de chaîne en C # 6):

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

    }
}

Usage:

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

J'utilise presque de manière excessive (c'est simple et ça marche)

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

Ensuite, si je dois reconvertir en double, j'ajoute une conversion.

(double)model.Split
0
ransems