2013-06-04 11 views
22

il mio modello:indesiderati decimale troncamento

public class Product 
{ 
    ... 
     public decimal Fineness { get; set; } 
    ... 
} 

Semina il database:

new List<Product> 
     { 
      new Product { ..., Fineness = 0.757M, ... }, 
      new Product { ..., Fineness = 0.674M, ... }, 
      new Product { ..., Fineness = 0.475M, ... } 
     }.ForEach(p => context.Products.Add(p)); 

interrogare il database per verificare la semina:

var products = db.Products.ToList(); 
foreach (var p in products) 
{ 
    S.D.Debug.WriteLine("ProductList: {0}, {1}", p.Name, p.Fineness); 
} 

Console in uscita:

ProductList: Test Product, 0.75 
ProductList: Test Product, 0.67 
ProductList: Test Product, 0.47  

Sto facendo qualcosa di veramente stupido o qualcosa ??? Tutto viene troncato a 2 cifre decimali.

Solution - Grazie a Patrick:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Product>().Property(x => x.Fineness).HasPrecision(10, 5); 
} 
+3

Avete configurato la precisione su Entity Framework? –

+0

@PatrickMagee: la soluzione. Grazie. Vedi l'aggiornamento in questione. – Gravy

+1

@Gravy Dovrebbe ottenere che Patrick Magee pubblichi tale risposta in modo che tu possa accettarlo;) –

risposta

20

In modo da avere i vostri modelli di entità standard definito, qui è prodotto con id e decimali, insieme con qualsiasi altra cosa che necessiti, ecc.

Quindi ho definito un n initlizer, nel qual caso il database cadrà e ricrea ogni informazione seed fornita, ogni volta che eseguo ed eseguo la mia applicazione, questo verrà chiamato.

public class Initializer : DropCreateDatabaseAlways<Context> 
{ 
    protected override void Seed(Context context) 
    { 
     // note how i am specifying it here as 4 digits after the decimal point 
     // and for the second one, 3 digits 
     // this is where EF precision must be configured so you can expect 
     // the values you tell EF to save to the db 
     context.Products.Add(new Product() {Id = 1, Fineness = 145.2442m}); 
     context.Products.Add(new Product() {Id = 2, Fineness = 12.341m}); 
    } 
} 

public class Context : DbContext 
{ 
    public IDbSet<Product> Products { get; set; } 

    public Context() 
    { 
     // I always explicitliy define how my EF should run, but this is not needed for the answer i am providing you 
     Configuration.AutoDetectChangesEnabled = true; 
     Configuration.ProxyCreationEnabled = true; 
     Configuration.LazyLoadingEnabled = true; 
     Configuration.ValidateOnSaveEnabled = true; 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // so here, I am override the model configuration which is what 
     // EF can use in order to set-up the behaviour of how everything 
     // is configured in the database, from associations between 
     // multiple entities and property validation, Null-able, Precision, required fields etc 
     modelBuilder.Configurations.Add(new ProductConfiguration()); 
    } 
} 

public class ProductConfiguration : EntityTypeConfiguration<Product> 
{ 
    public ProductConfiguration() 
    { 
     ToTable("Product"); 
     HasKey(x => x.Id).Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     // HAS PRECISION. 
     // Enforces how the value is to be stored in the database 
     // Here you can see I set a scale of 3, that's 3 digits after 
     // the decimal. Notice how in my seed method, i gave a product 4 digits! 
     // That means it will NOT save the product with the other trailing digits. 
     Property(x => x.Fineness).HasPrecision(precision: 10, scale: 3); 
    } 
} 

Con SQL Server Esplora oggetti, posso vedere il mio prodotto Esempio LocalDB ho fatto vedere come EF configurato il mio database.

enter image description here

[TestFixture] 
public class Tests 
{ 
    [Test] 
    public void Test() 
    { 
     Database.SetInitializer(new Initializer()); 

     using (var ctx = new Context()) 
     { 
      // assert our findings that it is indeed not what we actually specified in the seed method, because of our Entity configuration with HasPrecision. 
      Product product1 = ctx.Products.Find(1); 
      Assert.AreEqual(145.244m, product1.Fineness); 

      Product product2 = ctx.Products.Find(2); 
      Assert.AreEqual(12.341m, product2.Fineness); 
     }   
    } 
} 

Unit Test has run, seeded the db and we asserted our assumption

così abbiamo bisogno per garantire il database sa come si deve conservare il nostro valore decimale, configurando la nostra entità utilizzando la configurazione Model Builder di Entity Framework, utilizzando il FluentApi, possiamo impostare i tratti di proprietà tramite EntityTypeConfiguration<T>.

+6

Questa è una spiegazione sorprendente. Tuttavia, aggiungere solo quanto segue alla proprietà di mappatura (subito dopo la query LINQ) ha aiutato a risolvere il mio problema molto simile: '.HasPrecision (precisione: 10, scala: 3);' – user1835017

0

qui è buono tutorial per la formattazione dei numeri decimali

D.Debug.WriteLine("ProductList: {0}, {1:0.000}", p.Name, p.Fineness); 

// just two decimal places 
String.Format("{0:0.00}", 123.4567);  // "123.46" 
String.Format("{0:0.00}", 123.4);   // "123.40" 
String.Format("{0:0.00}", 123.0);   // "123.00" 

// max. two decimal places 
String.Format("{0:0.##}", 123.4567);  // "123.46" 
String.Format("{0:0.##}", 123.4);   // "123.4" 
String.Format("{0:0.##}", 123.0);   // "123" 

// at least two digits before decimal point 
String.Format("{0:00.0}", 123.4567);  // "123.5" 
String.Format("{0:00.0}", 23.4567);  // "23.5" 
String.Format("{0:00.0}", 3.4567);  // "03.5" 
String.Format("{0:00.0}", -3.4567);  // "-03.5" 

//Zero formatting 
String.Format("{0:0.0}", 0.0);   // "0.0" 
String.Format("{0:0.#}", 0.0);   // "0" 
String.Format("{0:#.0}", 0.0);   // ".0" 
String.Format("{0:#.#}", 0.0);   // "" 
+1

Controllato questo, grazie per il collegamento davvero utile ... ma sfortunatamente non è la mia soluzione. Sembra che il decimale venga troncato al momento dell'archiviazione nel database ... i valori ora appaiono come '0.750',' 0.670' e '0.470' nell'output della console – Gravy