Entity Framework 7 Imposta la precisione decimale per il builder del modello

entity-framework-core

Domanda

Ho cercato di capire come impostare la precisione decimale per EF7 (Beta 4) senza fortuna.

Mi aspettavo di fare qualcosa come:

modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).Precision(10, 6)

Questo non sembra essere disponibile, ma sono stato in grado di trovare la seguente classe nel repository in GitHub:

https://github.com/aspnet/EntityFramework/blob/7.0.0-beta4/src/EntityFramework.Relational/RelationalDecimalTypeMapping.cs

Non ci sono esempi di utilizzo delle classi RelationalTypeMapping o delle firme del metodo con loro. Forse questo è solo usato come parte della API di mappatura per il recupero delle informazioni?

Un altro posto che potrei aspettarmelo è il seguente:

modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).ForRelational().ColumnType() 

o

modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).ForSqlServer().ColumnType()

Questi prendono solo una stringa, questa funzionalità non è ancora stata implementata o sto semplicemente cercando il posto giusto?

Modifica: ho appena capito che la stringa è probabilmente per il tipo di soluzione .ColumnType ("decimal (10,6)") fino a quando non viene ulteriormente sviluppata, non mi dispiacerebbe comunque ottenere qualche chiarimento, poiché preferirei non utilizzare le stringhe per questo

Modifica: dopo aver chiarito da bricelam ho finito per creare la seguente estensione da utilizzare per ora per evitare l'uso della stringa, e apprezzo la semplicità del loro approccio:

public static RelationalPropertyBuilder DecimalPrecision(this RelationalPropertyBuilder propertyBuilder, int precision, int scale)
    {
        return propertyBuilder.ColumnType($"decimal({precision},{scale})");
    }

Esempio di utilizzo:

modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).ForRelational().DecimalPrecision(10,6);

Modifica: apportare modifiche per RC1

Non li ho ancora testati, ma ho semplicemente gettato insieme i seguenti 2 esempi di ciò che probabilmente sarà simile a RC1

    public static PropertyBuilder DecimalPrecision(this PropertyBuilder propertyBuilder, string precision, string scale)
    {
        return propertyBuilder.HasColumnType($"decimal({precision},{scale})");
    }

    public static PropertyBuilder SqlDecimalPrecision(this PropertyBuilder propertyBuilder, string precision, string scale)
    {
        return propertyBuilder.ForSqlServerHasColumnType($"decimal({precision},{scale})");
    }

Dal momento che non ho ancora provato questo non sono sicuro quale sarebbe l'uso corretto tra "HasColumnType" o "ForSqlServerHasColumnType", ma si spera che questo indicherà qualcuno nella giusta direzione.

Risposta accettata

La tua soluzione è il design che intendevamo. Invece di avere un sacco di "sfaccettature" puoi impostare un tipo come precisione, scala, lunghezza massima, unicode / ansi, lunghezza fissa / variabile, ecc. Abbiamo deciso di mantenerlo semplice: se il tipo di mappatura di default non è quello vuoi, dicci che tipo usare. Si è parlato di tornare su questa decisione e di reintrodurre le "sfaccettature". Se ti senti fortemente, ti incoraggio a creare un nuovo problema .

Si noti inoltre che ci sono un sacco di altri bug nella mappatura dei tipi in questo momento, ma dovrebbero essere corretti al momento del rilascio di beta5.


Risposta popolare

L'esempio mostrato sembra essere superato come da EF RC1.

Ecco come ho impostato la precisione su un campo decimale.

Dì che ho un'entità

public class Review
{
    public int ReviewId { get; set; }
    public decimal TotalScore { get; set; } //I want a precision field in DB
    public DateTime CreatedOn { get; set; }
    [Timestamp]
    public byte[] RowVersion { get; set; }
}

quindi nella mia classe di contesto, sulla creazione di modelli, istanziato la mappatura (potrei fare la mappatura lì, ma mi piace tenerla separata)

public class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options ) : base(options)
    {
    }

    public DbSet<Review> Reviews { get; set; }
    //etc.

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Mappings
        new ReviewMap(modelBuilder.Entity<Review>());
        //etc..
    }
}

e poi la mappatura. Ricordarsi di utilizzare lo spazio dei nomi in cui sono presenti le estensioni del modello:

using Microsoft.Data.Entity; //here is where the extensions are
public class ReviewMap
{
    public ReviewMap(EntityTypeBuilder<Review> entityBuilder)
    {
        entityBuilder.HasKey(r => r.ReviewId);

        //Using the column type extension
        entityBuilder.Property(r => r.TotalScore)
            .HasColumnType($"decimal(5,2)")
            .IsRequired(true);

        //and this has nothing to do with the example but it's interesting
        //to show how to use Sql command to automatically fulfil a value 
        //when adding a new Entity
        entityBuilder.Property(r => r.CreatedOn)
            .ValueGeneratedOnAdd()
            .HasDefaultValueSql("GETUTCDATE()")
            .IsRequired(true);
    }
}



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché