J'expérimente cette approche avec le code d'abord, mais je découvre maintenant qu'une propriété de type System.Decimal est mappée sur une colonne sql de type décimal (18, 0).
Comment définir la précision de la colonne de base de données?
c#
.net
entity-framework
ef-code-first
decimal
Dave Van den Eynde
la source
la source
[Column(TypeName = "decimal(18,4)")]
attribut pour vos propriétés décimalesRéponses:
La réponse de Dave Van den Eynde est désormais obsolète. Il y a 2 changements importants, à partir d'EF 4.1, la classe ModelBuilder est maintenant DbModelBuilder et il y a maintenant une méthode DecimalPropertyConfiguration.HasPrecision qui a une signature de:
où précision est le nombre total de chiffres que la base de données stockera, quel que soit l'endroit où le point décimal tombe et l'échelle est le nombre de décimales qu'elle stockera.
Par conséquent, il n'est pas nécessaire de parcourir les propriétés comme indiqué, mais le peut simplement être appelé depuis
la source
System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder
base.OnModelCreating(modelBuilder);
. Était-ce intentionnel ou simplement victime de taper du code en ligne plutôt que dans un IDE?Si vous souhaitez définir la précision pour tous
decimals
dans EF6, vous pouvez remplacer la valeur par défautDecimalPropertyConvention
convention utilisée dansDbModelBuilder
:Le défaut
DecimalPropertyConvention
par dans EF6 mappe lesdecimal
propriétés àdecimal(18,2)
colonnes.Si vous souhaitez uniquement que les propriétés individuelles aient une précision spécifiée, vous pouvez définir la précision de la propriété de l'entité sur le
DbModelBuilder
:Ou, ajoutez un
EntityTypeConfiguration<>
pour l'entité qui spécifie la précision:la source
J'ai passé un bon moment à créer un attribut personnalisé pour cela:
l'utiliser comme ça
et la magie se produit lors de la création du modèle avec une certaine réflexion
la première partie consiste à obtenir toutes les classes dans le modèle (mon attribut personnalisé est défini dans cet assemblage, donc je l'ai utilisé pour obtenir l'assemblage avec le modèle)
le deuxième foreach obtient toutes les propriétés de cette classe avec l'attribut personnalisé et l'attribut lui-même afin que je puisse obtenir les données de précision et d'échelle
après ça je dois appeler
donc j'appelle le modelBuilder.Entity () par réflexion et le stocke dans la variable entityConfig puis je construis l'expression lambda "c => c.PROPERTY_NAME"
Après cela, si la décimale est nulle, j'appelle le
méthode (j'appelle cela par la position dans le tableau, ce n'est pas l'idéal je sais, toute aide sera très appréciée)
et si ce n'est pas nullable j'appelle le
méthode.
Ayant la DecimalPropertyConfiguration j'appelle la méthode HasPrecision.
la source
MethodInfo methodInfo = entityConfig.GetType().GetMethod("Property", new[] { lambdaExpression.GetType() });
pour obtenir la surcharge correcte. semble fonctionner jusqu'à présent.À l'aide de
DecimalPrecisonAttribute
from KinSlayerUY, dans EF6, vous pouvez créer une convention qui gérera les propriétés individuelles qui ont l'attribut (par opposition à la définition de laDecimalPropertyConvention
même chose dans cette réponse qui affectera toutes les propriétés décimales).Puis dans votre
DbContext
:la source
Precision
, je recommande de définir la limite supérieure à 28 (donc> 28
dans votre état). Selon la documentation MSDN,System.Decimal
ne peut représenter qu'un maximum de 28 à 29 chiffres de précision ( msdn.microsoft.com/en-us/library/364x0z75.aspx ). De plus, l'attribut déclareScale
commebyte
, ce qui signifie que votre préconditionattribute.Scale < 0
n'est pas nécessaire.System.Decimal
non. Par conséquent, cela n'a aucun sens de fixer la condition préalable de limite supérieure à quelque chose de plus grand que 28;System.Decimal
ne peut pas représenter des nombres aussi grands, apparemment. Sachez également que cet attribut est utile pour les fournisseurs de données autres que SQL Server. Par exemple, lenumeric
type de PostgreSQL prend en charge jusqu'à 131072 chiffres de précision.decimal(38,9)
colonne tiendra heureux,System.Decimal.MaxValue
mais pas unedecimal(28,9)
colonne. Il n'y a aucune raison de limiter la précision à seulement 28.Apparemment, vous pouvez remplacer la méthode DbContext.OnModelCreating () et configurer la précision comme ceci:
Mais c'est un code assez fastidieux lorsque vous devez le faire avec toutes vos propriétés liées au prix, alors j'ai trouvé ceci:
Il est recommandé d'appeler la méthode de base lorsque vous remplacez une méthode, même si l'implémentation de base ne fait rien.
Mise à jour: cet article a également été très utile.
la source
base.OnModelCreating(modelBuilder);
soit nécessaire d' appeler . À partir des métadonnées DbContext dans VS:The default implementation of this method does nothing, but it can be overridden in a derived class such that the model can be further configured before it is locked down.
Entity Framework Ver 6 (Alpha, rc1) a quelque chose appelé Conventions personnalisées . Pour définir la précision décimale:
Référence:
la source
cela fonctionnera avec les premières migrations de code EF Core comme décrit ici .
la source
The store type 'decimal(18,2)' could not be found in the SqlServer provider manifest
cette ligne de code pourrait être un moyen plus simple de réaliser la même chose:
la source
- POUR EF CORE - avec utilisation de System.ComponentModel.DataAnnotations;
utilisation
[Column
(TypeName
= "decimal
( précision , échelle )")]
Précision = nombre total de caractères utilisés
Échelle = nombre total après le point. (facile à confondre)
Exemple :
Plus de détails ici: https://docs.microsoft.com/en-us/ef/core/modeling/relational/data-types
la source
Dans EF6
la source
Vous pouvez toujours dire à EF de le faire avec les conventions de la classe Context dans la fonction OnModelCreating comme suit:
Cela s'applique uniquement à Code First EF fyi et s'applique à tous les types décimaux mappés à la base de données.
la source
Remove<DecimalPropertyConvention>();
avant leAdd(new DecimalPropertyConvention(18, 4));
. Je pense qu'il est étrange que ce ne soit pas simplement remplacé automatiquement.En utilisant
Vous pouvez simplement mettre cet attribut dans votre modèle:
la source
Vous pouvez trouver plus d'informations sur MSDN - facette du modèle de données d'entité. http://msdn.microsoft.com/en-us/library/ee382834.aspx Complet recommandé.
la source
Réel pour EntityFrameworkCore 3.1.3:
une solution dans OnModelCreating:
la source
L'attribut personnalisé de KinSlayerUY a bien fonctionné pour moi mais j'ai eu des problèmes avec ComplexTypes. Ils étaient mappés en tant qu'entités dans le code d'attribut et ne pouvaient donc pas être mappés en tant que ComplexType.
J'ai donc étendu le code pour permettre ceci:
la source
@ Mark007, j'ai changé les critères de sélection de type pour chevaucher les propriétés DbSet <> du DbContext. Je pense que c'est plus sûr car il y a des moments où vous avez des classes dans l'espace de noms donné qui ne devraient pas faire partie de la définition du modèle ou elles le sont mais ne sont pas des entités. Ou vos entités peuvent résider dans des espaces de noms ou des assemblages distincts et être regroupées dans un seul contexte.
De plus, même si cela est peu probable, je ne pense pas qu'il soit sûr de s'appuyer sur l'ordre des définitions de méthode, il est donc préférable de les extraire avec la liste de paramètres. (.GetTypeMethods () est une méthode d'extension que j'ai construite pour fonctionner avec le nouveau paradigme TypeInfo et qui peut aplatir les hiérarchies de classes lors de la recherche de méthodes).
Notez que OnModelCreating délègue à cette méthode:
la source