Столбец EF Code First Readonly

Сначала я использую EF Code с первым подходом к базе данных. "с Database.SetInitializer (null);"

В моей таблице есть два столбца createddate и correcddate. Ими управляет SQL Server с помощью триггеров. Идея состоит в том, что при вводе данных эти столбцы получают данные через триггеры.

Теперь я хочу сделать это только для чтения с первой точки зрения EF Code. Т.е. Я хочу видеть в своем приложении даты создания и внесения изменений, но я не хочу изменять эти данные.

Я пробовал использовать частные модификаторы в сеттере, но безуспешно. Когда я пытался добавить новые данные в таблицу, он пытался ввести дату DateTime.Max в базу данных, которая выдает ошибку с SQL-сервера.

Любая идея?


person daehaai    schedule 03.07.2011    source источник


Ответы (2)


Вы не можете использовать частные модификаторы, потому что EF сам должен устанавливать ваши свойства при загрузке вашей сущности, а Code First может делать это только тогда, когда свойство имеет общедоступный установщик (в отличие от EDMX, где частные установщики возможны (1), (2)).

Что вам нужно сделать, так это отметить свой CreatedDate DatabaseGeneratedOption.Identity и AmendDate DatabaseGeneratedOption.Computed. Это позволит EF правильно загружать данные из базы данных, перезагружать данные после вставки или обновления, чтобы объект был актуальным в вашем приложении, и в то же время он не позволит вам изменить значение в приложении, потому что значение, установленное в приложение никогда не будет передано в базу данных. С объектно-ориентированной точки зрения это не очень хорошее решение, но с точки зрения функциональности это именно то, что вам нужно.

Вы можете сделать это либо с аннотациями к данным:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime CreatedDate { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime AmendDate { get; set; }

Или с плавным API в OnModelCreating переопределении в производном контексте:

modelBuilder.Entity<YourEntity>() 
            .Property(e => e.CreatedDate)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<YourEntity>()
            .Property(e => e.AmendDate)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
person Ladislav Mrnka    schedule 03.07.2011
comment
Спасибо за быстрый ответ. В чем разница между DatabaseGeneratedOption.Identity и DatabaseGeneratedOption.Computed? Кажется, я не могу найти подробностей об этом в Интернете. thx edit: Не отвечайте, что я получил свой ответ: msdn.microsoft.com/en-us/library/. Я дам вам знать, как это происходит большое спасибо - person daehaai; 04.07.2011
comment
когда я помещаю атрибут [DatebaseGenerated (DatabaseGeneratedOption.Identity)] для свойства CreatedDate, которое я получаю, столбец Update-Database: Identity 'CreatedDate' должен иметь тип данных int, bigint, smallint, tinyint или десятичный или числовой со шкалой 0 и не может быть обнуляемым. - person koraytaylan; 11.10.2011
comment
У меня такая же проблема. Какие-нибудь решения? - person ridermansb; 12.10.2011
comment
@koraytaylan - Не используйте DatabaseGeneratedOption.Identity для полей даты. Вместо этого используйте DatabaseGeneratedOption.Computed, что предложил Ладислав в своем ответе. - person CptRobby; 08.03.2014

EF core 1.1 или более поздние версии да, вы можете использовать свойство только для чтения в классах poco. Что вам нужно сделать, так это использовать резервное поле.

public class Blog
{
    private string _validatedUrl;

    public int BlogId { get; set; }

    public string Url
    {
        get { return _validatedUrl; }
    }

    public void SetUrl(string url)
    {
        using (var client = new HttpClient())
        {
            var response = client.GetAsync(url).Result;
            response.EnsureSuccessStatusCode();
        }

        _validatedUrl = url;
    }
}

класс MyContext: DbContext {общедоступные блоги DbSet {получить; набор; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .HasField("_validatedUrl");
}

}

и беглый api ...

modelBuilder.Entity<Blog>()
    .Property(b => b.Url)
    .HasField("_validatedUrl")
    .UsePropertyAccessMode(PropertyAccessMode.Field);

Взгляните сюда…

person ORÇUN GÜZEN    schedule 10.08.2018