с Entity Framework 5.0 и ODP.NET. Я пытаюсь создать первый код DbContext для моей существующей базы данных Oracle. Я знаю, что этот подход официально не поддерживается ODP, но, возможно, существует обходное решение для единственной проблемы, которую мне еще нужно решить.
Все мои таблицы имеют ключи типа NUMBER(18,0)
. Это простой пример:
Таблица
> DESCRIBE T_USER
KUSER NOT NULL NUMBER(18,0)
Объект домена
public class User
{
public long Id { get; set; }
/* ... */
}
Конфигурирование карт
modelBuilder.Entity<User>()
.ToTable("T_USER");
modelBuilder.Entity<User>()
.Property<long>(x => x.Id)
.IsRequired()
.HasColumnType("number")
.HasColumnName("KUSER");
Я не могу указать атрибут Precision, хотя, потому что только DecimalPropertyConfiguration
класс (.Property Свойство()) выставляет точность и масштаб свойства.
В результате все переведенные запросы содержат номер CAST AS с точностью до 19 цифр (сопоставление по умолчанию для Int64), например: SELECT CAST ("Extent1". "KUSER" AS number (19,0)) AS "C1",/*... */
Те же самые действия выполняются в предложениях JOIN и WHERE с сильным воздействием на каждый запрос.
В XML файле EDMX, который я устарел, поскольку я надеюсь, что не буду использовать его в будущем, у меня была эта строка:
<Property Name="KUSER" Type="number" Nullable="false" Precision="18" />
Можно ли вручную установить прецизионность свойства после создания модели EF?
Или, возможно, есть способ расширить классы конфигурации EF и добавить пользовательскую NumberPropertyConfiguration
которая предоставляет свойство Precision. Тот факт, что пространство имен Edm является внутренним, остановило меня от продолжения этого последнего пути.
decimal
типом С#, потому что мне пришлось бы переписать почти весь слой домена.long
свойство для переноса скрытого decimal
, поскольку long
поле должно использоваться в связях запросов LINQ-to-SQL и выбирать.HasColumnType("number")
в PrimitivePropertyConfiguration
, но результат тот же. Возможно ли изменить грани собственности, пройдя MetadataWorkspace
?
(this as IObjectContextAdapter).ObjectContext.MetadataWorkspace
Я постараюсь сделать это как можно скорее и обновить результаты.
Нет, MetadataWorkspace
доступен только для чтения.
Нет, вы не можете этого сделать. Если вы используете Code First, модель определяется вашим кодом. Если ваш код говорит, что свойство long
, оно не будет отображаться как столбец NUMBER()
в базе данных.
Единственными прямыми обходными решениями, о которых я могу думать, являются те, о которых вы упоминаете, но вы хотите избежать.
Вы все равно можете использовать mapper, например AutoMapper (подробнее здесь), который позволяет вам сопоставлять ваши объекты EF с объектами вашего домена. В зависимости от того, как реализован ваш код, это может сработать, но, если вы протестируете функциональные возможности EF LINQ в логике вашего домена, это не сработает. Вы можете попробовать использовать AutoMapper IQueryable Extensions, но я не уверен, что они будут работать в вашем случае использования.