EF 5.0 Oracle Code First set Точность для числовых типов

1

с 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 доступен только для чтения.

  • 0
    Я обновил вопрос подробностью, которую я пропустил, и другим возможным решением (надеюсь).
Теги:
entity-framework
ef-code-first

1 ответ

1
Лучший ответ

Нет, вы не можете этого сделать. Если вы используете Code First, модель определяется вашим кодом. Если ваш код говорит, что свойство long, оно не будет отображаться как столбец NUMBER() в базе данных.

Единственными прямыми обходными решениями, о которых я могу думать, являются те, о которых вы упоминаете, но вы хотите избежать.

Вы все равно можете использовать mapper, например AutoMapper (подробнее здесь), который позволяет вам сопоставлять ваши объекты EF с объектами вашего домена. В зависимости от того, как реализован ваш код, это может сработать, но, если вы протестируете функциональные возможности EF LINQ в логике вашего домена, это не сработает. Вы можете попробовать использовать AutoMapper IQueryable Extensions, но я не уверен, что они будут работать в вашем случае использования.

  • 0
    Благодарю. Я пропускаю функциональные возможности EF в моей доменной логике, так как думаю, что в этом весь смысл наличия EF. Я посмотрю на тех картографов, которых вы упомянули, чтобы выяснить, могут ли они помочь.
  • 0
    Я могу согласиться с тем, что иногда полезно и эффективно просачивать функции EF в логику предметной области. Но это не единственный, а самый подходящий для всех случаев. Было бы интересно, если бы вы показали, работают ли расширения IQueryable для вашего случая. Я никогда не пробовал это с таким типом сопоставления типа изменения ключевого столбца.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню