Расчетное поле, не запрошенное EF [duplicate]

Вы можете добавить unique index в group_id; если вы уверены, что group_id уникален.

Он может решить ваш случай без изменения запроса.

Поздний ответ, но он еще не упоминался в ответах. Возможно, он должен заполнить уже исчерпывающие ответы. По крайней мере, это разрешило мой случай, когда мне пришлось разбивать таблицу со слишком большим количеством полей.

8
задан sprocket12 11 January 2013 в 19:30
поделиться

3 ответа

Решение, которое я нашел, это:

  1. Убедитесь, что автоматическая миграция отключена. Это значит, что VS будет генерировать скрипт (свободный код api) для дальнейшей настройки, а не просто запускать его. Итак, в классе конфигурации:
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }
    
  2. Добавьте поле в класс и установите его так, как вычислено так, setter является приватным, потому что мы, очевидно, не можем записать в вычисленное поле:
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public string BreakdownNo { get; private set; }
    
  3. Затем создайте add-migration [xyz-name] в консоли диспетчера пакетов, чтобы сгенерировать код миграции, который будет отображаться в папке миграций с заданным именем.
  4. Внутри миграции запишите код в Up() и добавьте собственный SQL так:
    public override void Up()
    {
        //AddColumn("dbo.Calls", "BreakdownNo", c => c.String());
        Sql("ALTER TABLE dbo.Calls ADD BreakdownNo AS ('BD'+RIGHT('00000'+ CAST(Id AS VARCHAR), 6))");
    }
    
  5. Сделайте update-database в PM, и он должен правильно добавить вычисленный столбец.

ДАЛЬНЕЙШИЕ ПРИМЕЧАНИЯ: Если вы получите неправильную форму, тогда вам придется вернуться к миграции, выполнив update-database -targetMigration: [name of migration to go back to], затем сделайте еще add-migration name и измените формулу там, закончив обновлением-базой данных. Может быть, лучший способ, но это то, что я нашел и использовал.

Однако я не нашел способ сделать поле еще не сохраненным.

8
ответ дан sprocket12 31 August 2018 в 13:24
поделиться

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

Я столкнулся с сбоем при выполнении этого запроса:

oDb.LogEntries.Where(Function(LogEntry) LogEntry.LogTime = dDate).SingleOrDefault

Сообщение об ошибке:

Свойство «MinutesOffline» в «LogEntry» не может быть установлено в значение «System.Int32». Вы должны установить это свойство в ненулевое значение типа «System.Single».

Как мы видим, EF 6.2 пытается записать значение для свойства. Независимо от того, связано ли это с тем, что EF внутренне пытается писать на Private Set, я не знаю. Похоже на это. Но конечный результат имеет значение: утверждение терпит неудачу.

Вместо того, чтобы установить столбец в DatabaseGeneratedOption.Computed, я полностью проигнорировал его: Builder.Entity(Of LogEntry).Ignore(Function(LogEntry) LogEntry.MinutesOffline).

Это позволило мне для создания свойства только для чтения:

Public ReadOnly Property MinutesOffline As Single
  Get
    Return IIf(Me.Scale < 1, 5, 0)
  End Get
End Property

Он также имеет дополнительное преимущество, которое нам не нужно комментировать любые строки в сгенерированной миграции.

У нас все еще есть чтобы пользовательский вызов Sql() в Up():

ALTER TABLE [LogEntries] ADD [MinutesOffline] AS (IIF([Scale] < 1, 5, 0)) PERSISTED

... и ключевое слово PERSISTED работают здесь. Это становится стойкой вычисленной колонкой.

YMMV

0
ответ дан InteXX 31 August 2018 в 13:24
поделиться

Почему бы не назвать sql следующим образом:

public class demo
{
    void demoMethod()
    {
        Model1 model = new Model1();//Model1 : DbContext
        model.Database.ExecuteSqlCommand("alter table Results drop column Total; alter table Results add Total AS (Arabic + English + Math + Science)");
    }
}
1
ответ дан user 31 August 2018 в 13:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: