Я экспериментирую с этим первым подходом к коду, но теперь выясняю, что свойство типа System.Decimal отображается на столбец sql типа decimal (18, 0).
Как мне установить точность столбца базы данных?
c#
.net
entity-framework
ef-code-first
decimal
Дэйв Ван ден Эйнде
источник
источник
[Column(TypeName = "decimal(18,4)")]
атрибута для ваших десятичных свойствОтветы:
Ответ от Дейва Ван ден Эйнде сейчас устарел. Есть 2 важных изменения, начиная с EF 4.1 и далее, класс ModelBuilder теперь называется DbModelBuilder, и теперь существует метод DecimalPropertyConfiguration.HasPrecision, имеющий сигнатуру:
где точность - это общее количество цифр, которые будет хранить БД, независимо от того, где находится десятичная точка, а шкала - это количество десятичных знаков, которые она будет хранить.
Поэтому нет необходимости перебирать свойства, как показано, но их можно просто вызвать из
источник
System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder
base.OnModelCreating(modelBuilder);
. Было ли это намеренно или просто жертвой ввода кода онлайн вместо IDE?Если вы хотите установить точность для всех
decimals
в EF6, вы можете заменитьDecimalPropertyConvention
соглашение по умолчанию, используемое вDbModelBuilder
:Значение по умолчанию
DecimalPropertyConvention
в EF6 отображаетdecimal
свойства вdecimal(18,2)
столбцы.Если вы хотите, чтобы отдельные свойства имели указанную точность, вы можете установить точность для свойства объекта в
DbModelBuilder
:Или добавьте
EntityTypeConfiguration<>
для объекта, который указывает точность:источник
Я хорошо провел время, создавая собственный атрибут для этого:
используя это так
и магия происходит при создании модели с некоторым отражением
первая часть - получить все классы в модели (в этой сборке определен мой пользовательский атрибут, поэтому я использовал его для получения сборки с моделью)
второй foreach получает все свойства в этом классе с помощью пользовательского атрибута и самого атрибута, чтобы я мог получить данные о точности и масштабе
после этого мне нужно позвонить
поэтому я вызываю modelBuilder.Entity () с помощью отражения и сохраняю его в переменной entityConfig, затем строю лямбда-выражение "c => c.PROPERTY_NAME"
После этого, если десятичная дробь обнуляется, я называю
метод (я называю это положением в массиве, это не идеально, я знаю, любая помощь будет высоко ценится)
и если это не обнуляемо, я называю
метод.
Имея DecimalPropertyConfiguration, я вызываю метод HasPrecision.
источник
MethodInfo methodInfo = entityConfig.GetType().GetMethod("Property", new[] { lambdaExpression.GetType() });
чтобы получить правильную перегрузку. кажется, работает до сих пор.Используя команду
DecimalPrecisonAttribute
from KinSlayerUY, в EF6 вы можете создать соглашение, которое будет обрабатывать отдельные свойства, которые имеют атрибут (в отличие от установкиDecimalPropertyConvention
подобного в этом ответе, который повлияет на все десятичные свойства).Тогда в вашем
DbContext
:источник
Precision
, то я рекомендую установить верхнюю границу на 28 (то есть> 28
в вашем состоянии). Согласно документации MSDN,System.Decimal
точность может составлять не более 28-29 цифр ( msdn.microsoft.com/en-us/library/364x0z75.aspx ). Кроме того, атрибут объявляетсяScale
какbyte
, что означает, что ваше предварительное условиеattribute.Scale < 0
не требуется.System.Decimal
нет. Поэтому нет смысла устанавливать верхнее предусловие на значение больше 28;System.Decimal
по-видимому, не может представлять такие большие числа. Также помните, что этот атрибут полезен для поставщиков данных, отличных от SQL Server. Например,numeric
тип PostgreSQL поддерживает до 131072 цифр точности.decimal(38,9)
столбца будет счастливым,System.Decimal.MaxValue
ноdecimal(28,9)
столбец - нет. Нет оснований ограничивать точность только до 28.По-видимому, вы можете переопределить метод DbContext.OnModelCreating () и настроить точность следующим образом:
Но это довольно утомительный код, когда вам нужно сделать это со всеми вашими ценовыми свойствами, поэтому я придумал это:
Рекомендуется вызывать базовый метод при переопределении метода, даже если базовая реализация ничего не делает.
Обновление: эта статья также была очень полезной.
источник
base.OnModelCreating(modelBuilder);
необходимо. Из метаданных DbContext в 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 версии 6 (Alpha, rc1) есть нечто, называемое пользовательскими соглашениями . Чтобы установить десятичную точность:
Ссылка:
источник
это будет работать с первыми миграциями кода EF Core, как описано здесь .
источник
The store type 'decimal(18,2)' could not be found in the SqlServer provider manifest
эта строка кода может быть более простым способом сделать то же самое:
источник
- ДЛЯ EF CORE - с использованием System.ComponentModel.DataAnnotations;
использовать
[Column
(TypeName
= "decimal
( точность , масштаб )")]
Точность = общее количество используемых символов
Масштаб = общее число после точки. (легко запутаться)
Пример :
Более подробная информация здесь: https://docs.microsoft.com/en-us/ef/core/modeling/relational/data-types
источник
В EF6
источник
Вы всегда можете сказать EF сделать это с соглашениями в классе Context в функции OnModelCreating следующим образом:
Это относится только к FY Code First EF и относится ко всем десятичным типам, отображаемым в БД.
источник
Remove<DecimalPropertyConvention>();
наступит раньшеAdd(new DecimalPropertyConvention(18, 4));
. Я думаю, что это странно, что не просто автоматически переопределяется.С помощью
Вы можете просто вставить этот атрибут в вашу модель:
источник
Вы можете найти больше информации о MSDN - аспекте Entity Data Model. http://msdn.microsoft.com/en-us/library/ee382834.aspx Полный рекомендуется.
источник
Актуально для EntityFrameworkCore 3.1.3:
какое-то решение в OnModelCreating:
источник
Пользовательский атрибут KinSlayerUY работал хорошо для меня, но у меня были проблемы с ComplexTypes. Они отображались как сущности в коде атрибута, поэтому их нельзя было сопоставить как ComplexType.
Поэтому я расширил код, чтобы учесть это:
источник
@ Mark007, я изменил критерии выбора типа, чтобы использовать свойства DbSet <> DbContext. Я думаю, что это безопаснее, потому что бывают случаи, когда в данном пространстве имен есть классы, которые не должны быть частью определения модели или они не являются сущностями. Или ваши сущности могут находиться в отдельных пространствах имен или отдельных сборках и объединяться в единый контекст.
Кроме того, хотя это маловероятно, я не думаю, что можно полагаться на порядок определений методов, поэтому лучше их извлекать с помощью списка параметров. (.GetTypeMethods () - это метод расширения, который я построил для работы с новой парадигмой TypeInfo и может сгладить иерархию классов при поиске методов).
Обратите внимание, что OnModelCreating делегирует этот метод:
источник