Каковы способы сделать свойство только генерируемым кодом

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

Я хочу, чтобы свойства абстрактного класса были ограничены от любых пользовательских модификаций, кроме изменений, сделанных кодом.

Чего я хочу достичь:

public abstract class SystemEntityBase
{
    /// <summary>
    /// Gets the date when entity was created.
    /// </summary>
    public DateTime Created { get; } = DateTime.UtcNow;

    /// <summary>
    /// Gets the date when entity was last active in the system.
    /// </summary>
    public DateTime LastActive { get; } = DateTime.UtcNow;
}

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

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

[ReadOnly(true)] помогает вообще?

Marc Gravell 25.12.2020 20:09

Вам также может понравиться такой подход.

Gert Arnold 25.12.2020 22:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
77
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы должны иметь возможность использовать свойства только для инициализации, если вы можете использовать С# 9.0.

Для свойств инициализации требуется c# 9 и либо .net 5, либо ручная копия необходимого типа mod-req. Определенно стоит попробовать - я просто говорю, что нужен не только С# 9.

Marc Gravell 25.12.2020 20:08

Но пользователь по-прежнему сможет установить значение свойства с помощью new SomeEntity {Created = ....}, чего, как я понимаю, не хочет OP.

Guru Stron 25.12.2020 20:14

Если я правильно понял проблему - вы можете попробовать использовать Backing Fields. Для вашего свойства Created это может выглядеть примерно так (по какой-то причине использование BackingFieldAttribute не сработало для меня с моими тестовыми настройками SQLite и postgres, но свободный API помог):

public class SomeEntity
{
    public DateTime Created => _created

    private DateTime _created = DateTime.UtcNow;    
}

И в OnModelCreating(ModelBuilder modelBuilder):

 modelBuilder.Entity<SomeEntity>()
     .Property(b => b.Created)
     .HasField("_test");

Также можно избавиться от необходимости настраивать все SomeEntity вручную с помощью некоторой магии отражения.

Другие вопросы по теме