Как получить доступ к вычисляемому столбцу в Entity Framework Code First?
Я использую Entity Framework Code First в моем приложении ASP.NET MVC. Один из моих классов имеет несколько столбцов, которые объединены вместе. Я храню эти столбцы в виде вычисляемых столбцов в таблицах, запустив в инициализатор базы данных таблицу изменений script. Скажем, класс выглядит следующим образом:
public class Bond
{
public decimal ParAmountOfIssuance { get; set; }
public decimal AccruedInterest { get; set; }
public decimal Premium { get; set; }
public decimal OriginalIssueDiscount { get; set; }
}
Альтернативный script выглядит примерно так:
alter table Bonds
add TotalSources as (ParAmountOfIssuance + AccruedInterest + Premium - OriginalIssueDiscount)
Я хочу, чтобы столбец Total Sources
был доступен для просмотра в веб-приложении. Какой лучший способ это сделать? Атрибут [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
не работает, потому что EF Code First создает таблицу из класса перед запуском alter script.
Любые предложения приветствуются.
Ответы
Ответ 1
У меня есть обходное решение.
Вы можете использовать только рассчитанное поле в существующей базе данных.
Если вы добавляете свое свойство в объект CF как:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public decimal TotalSources { get; set; }
и если вы добавите строку в свой script, которая удалит информацию о генерации этой базы данных:
DELETE FROM [dbo].[EdmMetadata]
CF предположит, что это существующая база данных, и она будет работать, я только что попробовал.
ОБНОВЛЕНИЕ. Я забыл, если вы добавите свойство в свой объект Bond, как это, тогда в вашем script вам нужно изменить его, чтобы он был рассчитан, а не добавлять его:)
Вы даже можете вручную "синхронизировать" базу данных и модель - в точке, где у вас все работает без этого поля, добавьте его в модель как рассчитанную, а в таблицу - как рассчитанную. Когда вы удаляете хэш из таблицы метаданных edm, CF будет работать, не пытаясь восстановить модель с базой данных.
Ответ 2
Это определенно не поддерживается - определение опции Computed
в пользовательском свойстве приведет к исключению. Код first = логический код. Если вам нужны пользовательские вычисленные свойства, сначала используйте базу данных. Единственной логикой базы данных, поддерживаемой первым кодом, является столбец идентификатора и временная метка.
Проблема в том, что вам нужен столбец, который будет помечен как вычисленный, но создание базы данных не позволит этого. Если столбец не помечен как вычисленный, он будет updatable = EF будет генерировать операторы обновления, пытающиеся обновить этот столбец, который не будет работать в базе данных.
Ответ 3
Я делаю вычисляемые столбцы в CF (WinForms), подобные этому (я не знаю, насколько это лучше):
Это один объект:
public class Result
{
public int ResultId { get; set; }
public int StudentId { get; set; }
public Student Student { get; set; }
public float Arabic { get; set; }
public float English { get; set; }
public float Math { get; set; }
public float Science { get; set; }
public float Total { get; set; }
}
Это Form2:
private void Form2_Load(object sender, EventArgs e)
{
Model1 model = new Model1();//Model1 : DbContext
model.Database.CreateIfNotExists();
model.Database.ExecuteSqlCommand("alter table Results drop column Total; alter table Results add Total AS (Arabic + English + Math + Science)");
var r1 = (from s in model.Students
join r in model.Results
on s.StudentId equals r.StudentId
select new { s.StudentName, r.Arabic, r.English, r.Science, r.Math, r.Total }).ToList();
dataGridView1.DataSource = r1;
}