web-dev-qa-db-de.com

Stellen Sie die Dezimalzahl (16, 3) für eine Spalte in Code First Approach in EF4.3 ein

Wie kann ich das machen :

private decimal _SnachCount;
[Required]
[DataType("decimal(16 ,3")]
public decimal SnachCount
{
    get { return _SnachCount; }
    set { _SnachCount = value; }
}

private decimal _MinimumStock;
[Required]
[DataType("decimal(16 ,3")]
public decimal MinimumStock
{
    get { return _MinimumStock; }
    set { _MinimumStock = value; }
}

private decimal _MaximumStock;
[Required]
[DataType("decimal(16 ,3")]
public decimal MaximumStock
{
    get { return _MaximumStock; }
    set { _MaximumStock = value; }
}

Nach dem Generieren der Datenbank mit diesem Teil meines Modells sind diese drei Spaltentypen dezimal (18,2). Warum? Was ist dieser Codefehler? wie kann ich das machen ?

39
Ali Foroughi

Das DataType Attribut ist ein Validierungsattribut. Sie müssen dies mit dem ModelBuilder tun.

public class MyContext : DbContext
{
    public DbSet<MyClass> MyClass;
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MyClass>().Property(x => x.SnachCount).HasPrecision(16, 3);
        modelBuilder.Entity<MyClass>().Property(x => x.MinimumStock).HasPrecision(16, 3);
        modelBuilder.Entity<MyClass>().Property(x => x.MaximumStock).HasPrecision(16, 3);
    }
}
74
dknaack

Sie können alle Dezimaleigenschaften in der Datenbank ändern. In Ihrem DBContext in der Methode OnModelCreating add line:

modelBuilder.Properties<decimal>().Configure(c => c.HasPrecision(18, 3));
31
Robert

Dies ist von der Antwort kopiert, die ich hier auf dieselbe Frage gepostet habe. https://stackoverflow.com/a/15386883/1186032 .


Ich hatte eine schöne Zeit, ein benutzerdefiniertes Attribut dafür zu erstellen:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class DecimalPrecisionAttribute : Attribute
{
    public DecimalPrecisionAttribute(byte precision, byte scale)
    {
        Precision = precision;
        Scale = scale;

    }

    public byte Precision { get; set; }
    public byte Scale { get; set; }

}

benutze es so

[DecimalPrecision(20,10)]
public Nullable<decimal> DeliveryPrice { get; set; }

und die Magie geschieht bei der Modellerstellung mit einigem Nachdenken

protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
    foreach (Type classType in from t in Assembly.GetAssembly(typeof(DecimalPrecisionAttribute)).GetTypes()
                                   where t.IsClass && t.Namespace == "YOURMODELNAMESPACE"
                                   select t)
     {
         foreach (var propAttr in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<DecimalPrecisionAttribute>() != null).Select(
                p => new { prop = p, attr = p.GetCustomAttribute<DecimalPrecisionAttribute>(true) }))
         {

             var entityConfig = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(classType).Invoke(modelBuilder, null);
             ParameterExpression param = ParameterExpression.Parameter(classType, "c");
             Expression property = Expression.Property(param, propAttr.prop.Name);
             LambdaExpression lambdaExpression = Expression.Lambda(property, true,
                                                                      new ParameterExpression[]
                                                                          {param});
             DecimalPropertyConfiguration decimalConfig;
             if (propAttr.prop.PropertyType.IsGenericType && propAttr.prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
             {
                 MethodInfo methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[7];
                 decimalConfig = methodInfo.Invoke(entityConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration;
             }
             else
             {
                 MethodInfo methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[6];
                 decimalConfig = methodInfo.Invoke(entityConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration;
             }

             decimalConfig.HasPrecision(propAttr.attr.Precision, propAttr.attr.Scale);
        }
    }
}

der erste Teil besteht darin, alle Klassen im Modell abzurufen (mein benutzerdefiniertes Attribut ist in dieser Assembly definiert, daher habe ich dieses verwendet, um die Assembly mit dem Modell abzurufen.)

das zweite foreach ruft alle Eigenschaften in dieser Klasse mit dem benutzerdefinierten Attribut und dem Attribut selbst ab, damit ich die Genauigkeits- und Skalierungsdaten abrufen kann

danach muss ich anrufen

modelBuilder.Entity<MODEL_CLASS>().Property(c=> c.PROPERTY_NAME).HasPrecision(PRECITION,SCALE);

also rufe ich die modelBuilder.Entity () durch Reflektion auf und speichere sie in der entityConfig-Variablen. Dann erstelle ich den Lambda-Ausdruck "c => c.PROPERTY_NAME"

Danach, wenn die Dezimalstelle nullable ist, rufe ich das auf

Property(Expression<Func<TStructuralType, decimal?>> propertyExpression) 

methode (ich nenne das die Position im Array, es ist nicht ideal, ich weiß, jede Hilfe wird sehr geschätzt)

und wenn es nicht nullable ist, nenne ich das

Property(Expression<Func<TStructuralType, decimal>> propertyExpression)

methode.

Mit der DecimalPropertyConfiguration rufe ich die HasPrecision-Methode auf.

20
KinSlayerUY

Also, was ich für mich arbeiten bekam, ist das:

public class RestaurantItemEntity : BaseEntity
{
    [Column(TypeName = "VARCHAR(128)")]
    [StringLength(128)]
    [Required]
    public string Name { get; set; }


    [Column(TypeName = "VARCHAR(1024)")]
    [StringLength(1024)]
    public string Description { get; set; }


    [Column(TypeName = "decimal(16,2)")]
    [Required]
    public decimal Price { get; set; }


    [Required]
    public RestaurantEntity Restaurant { get; set; }
}

Dies ist der erste EF-Code für .NET Core.

6
Vulovic Vukasin

Sie können die Genauigkeit von Dezimalstellen auch mit dem Code-First-Modellzuordnungsansatz wie folgt festlegen:

public class MyEntityMapping : EntityTypeConfiguration<MyEntity>
{
    public MyEntityMapping()
    {
        HasKey(x => x.Id);
        Property(x => x.Id).IsRequired();
        // .HasPrecision(precision, scale)
        // 'precision' = total number of digits stored,
        // regardless of where the decimal point falls 
        // 'scale' = number of decimal places stored
        Property(x => x.DecimalItem).IsRequired().HasPrecision(16, 6);
    }
}
1
RickL