Saya bereksperimen dengan pendekatan kode-pertama ini, tapi saya sekarang tahu bahwa properti tipe System.Decimal akan dipetakan ke kolom sql tipe desimal (18, 0).
Bagaimana cara mengatur ketepatan kolom database?
c#
.net
entity-framework
ef-code-first
decimal
Dave Van den Eynde
sumber
sumber
[Column(TypeName = "decimal(18,4)")]
atribut untuk properti desimal AndaJawaban:
Jawaban dari Dave Van den Eynde sudah ketinggalan zaman. Ada 2 perubahan penting, dari EF 4.1 dan seterusnya kelas ModelBuilder sekarang DbModelBuilder dan sekarang ada DecimalPropertyConfiguration.HasPrecision Method yang memiliki tanda tangan:
di mana presisi adalah jumlah total digit yang akan disimpan db, terlepas dari di mana titik desimal jatuh dan skala adalah jumlah tempat desimal yang akan disimpannya.
Oleh karena itu tidak perlu untuk beralih melalui properti seperti yang ditunjukkan tetapi hanya dapat dipanggil dari
sumber
System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder
base.OnModelCreating(modelBuilder);
. Apakah itu disengaja atau hanya menjadi korban pengetikan kode online alih-alih dalam IDE?Jika Anda ingin mengatur presisi untuk semua
decimals
di EF6, Anda dapat menggantiDecimalPropertyConvention
konvensi default yang digunakan diDbModelBuilder
:Default
DecimalPropertyConvention
di EF6 memetakandecimal
properti kedecimal(18,2)
kolom.Jika Anda hanya ingin masing-masing properti memiliki presisi yang ditentukan, maka Anda dapat mengatur presisi untuk properti entitas pada
DbModelBuilder
:Atau, tambahkan
EntityTypeConfiguration<>
entitas untuk yang menentukan presisi:sumber
Saya bersenang-senang membuat Atribut Khusus untuk ini:
menggunakannya seperti ini
dan keajaiban terjadi pada pembuatan model dengan beberapa refleksi
bagian pertama adalah untuk mendapatkan semua kelas dalam model (atribut khusus saya didefinisikan dalam perakitan itu jadi saya menggunakannya untuk mendapatkan perakitan dengan model)
foreach kedua mendapatkan semua properti di kelas itu dengan atribut khusus, dan atribut itu sendiri sehingga saya bisa mendapatkan data presisi dan skala
setelah itu saya harus menelpon
jadi saya memanggil modelBuilder.Entity () dengan refleksi dan menyimpannya dalam variabel entityConfig kemudian saya membangun ekspresi lambda "c => c.PROPERTY_NAME"
Setelah itu, jika desimalnya dapat dibatalkan saya panggil
metode (saya menyebutnya dengan posisi dalam array, itu tidak ideal saya tahu, bantuan apa pun akan sangat dihargai)
dan jika itu tidak dapat dibatalkan saya sebut
metode.
Memiliki DecimalPropertyConfiguration saya memanggil metode HasPrecision.
sumber
MethodInfo methodInfo = entityConfig.GetType().GetMethod("Property", new[] { lambdaExpression.GetType() });
untuk mendapatkan kelebihan yang benar. tampaknya bekerja sejauh ini.Dengan menggunakan
DecimalPrecisonAttribute
dari KinSlayerUY, di EF6 Anda dapat membuat konvensi yang akan menangani masing-masing properti yang memiliki atribut (yang bertentangan dengan pengaturanDecimalPropertyConvention
seperti pada jawaban ini yang akan memengaruhi semua properti desimal).Kemudian di Anda
DbContext
:sumber
Precision
, maka saya sarankan mengatur batas atas ke 28 (jadi> 28
dalam kondisi Anda). Menurut dokumentasi MSDN,System.Decimal
hanya dapat mewakili maksimum 28-29 digit presisi ( msdn.microsoft.com/en-us/library/364x0z75.aspx ). Atribut juga menyatakanScale
sebagaibyte
, yang berarti prasyarat Andaattribute.Scale < 0
tidak perlu.System.Decimal
tidak. Oleh karena itu tidak masuk akal untuk menetapkan prasyarat batas atas untuk sesuatu yang lebih besar dari 28;System.Decimal
tampaknya tidak dapat mewakili angka sebesar itu. Perlu diketahui juga bahwa atribut ini berguna untuk penyedia data selain SQL Server. Misalnya,numeric
tipe PostgreSQL mendukung hingga 131072 digit presisi.decimal(38,9)
kolom akan senang menahanSystem.Decimal.MaxValue
tetapidecimal(28,9)
kolom tidak akan. Tidak ada alasan untuk membatasi presisi hanya 28.Rupanya, Anda dapat mengganti metode DbContext.OnModelCreating () dan mengkonfigurasi presisi seperti ini:
Tapi ini kode yang cukup membosankan ketika Anda harus melakukannya dengan semua properti Anda yang berkaitan dengan harga, jadi saya datang dengan ini:
Adalah praktik yang baik bahwa Anda memanggil metode dasar ketika Anda menimpa metode, meskipun implementasi basis tidak melakukan apa pun.
Pembaruan: Artikel ini juga sangat membantu.
sumber
base.OnModelCreating(modelBuilder);
perlu menelepon . Dari metadata DbContext dalam 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) memiliki sesuatu yang disebut Konvensi Kustom . Untuk mengatur presisi desimal:
Referensi:
sumber
ini akan bekerja dengan migrasi pertama kode EF Core seperti dijelaskan di sini .
sumber
The store type 'decimal(18,2)' could not be found in the SqlServer provider manifest
baris kode ini bisa menjadi cara yang lebih sederhana untuk melakukan hal yang sama:
sumber
- UNTUK EF CORE - dengan menggunakan System.ComponentModel.DataAnnotations;
gunakan
[Column
(TypeName
= "decimal
( presisi , skala )")]
Presisi = Total jumlah karakter yang digunakan
Skala = Jumlah total setelah titik. (mudah bingung)
Contoh :
Lebih detail di sini: https://docs.microsoft.com/en-us/ef/core/modeling/relational/data-types
sumber
Di EF6
sumber
Anda selalu dapat memberi tahu EF untuk melakukan ini dengan konvensi di kelas Konteks di fungsi OnModelCreating sebagai berikut:
Ini hanya berlaku untuk Kode F EF Pertama dan berlaku untuk semua jenis desimal yang dipetakan ke db.
sumber
Remove<DecimalPropertyConvention>();
datang sebelumAdd(new DecimalPropertyConvention(18, 4));
. Saya pikir itu aneh bahwa tidak hanya ditimpa secara otomatis.Menggunakan
Anda cukup menaruh atribut itu di model Anda:
sumber
Anda dapat menemukan informasi lebih lanjut tentang MSDN - segi Model Data Entitas. http://msdn.microsoft.com/en-us/library/ee382834.aspx Direkomendasikan penuh.
sumber
Sebenarnya untuk EntityFrameworkCore 3.1.3:
beberapa solusi di OnModelCreating:
sumber
Atribut khusus KinSlayerUY bekerja dengan baik untuk saya, tetapi saya memiliki masalah dengan ComplexTypes. Mereka dipetakan sebagai entitas dalam kode atribut sehingga tidak dapat dipetakan sebagai ComplexType.
Karena itu saya memperpanjang kode untuk memungkinkan ini:
sumber
@ Mark007, saya telah mengubah kriteria pemilihan jenis untuk naik dari properti DbSet <> dari DbContext. Saya pikir ini lebih aman karena ada kalanya Anda memiliki kelas di namespace yang diberikan yang seharusnya tidak menjadi bagian dari definisi model atau mereka tetapi bukan entitas. Atau entitas Anda dapat berada di ruang nama atau majelis yang terpisah dan ditarik bersama menjadi satu Konteks sekali.
Juga, meskipun tidak mungkin, saya tidak berpikir itu aman untuk mengandalkan pemesanan definisi metode, jadi lebih baik menariknya dengan daftar Parameter. (.GetTypeMethods () adalah metode ekstensi yang saya bangun untuk bekerja dengan paradigma TypeInfo baru dan dapat meratakan hierarki kelas saat mencari metode).
Perhatikan bahwa OnModelCreating mendelegasikan metode ini:
sumber