Укажите столбец / поле EF Core только для чтения - PullRequest
0 голосов
/ 04 января 2019

У меня есть таблица SQL Server с определенными полями, которые устанавливаются базой данных через значения по умолчанию, которые после сохранения должны никогда не изменяться снова (например, DateCreated).

В компоновщике моделей классов Entity Framework Core 2.1 как мы «помечаем» поле как доступное только для чтения?Другими словами, я не хочу, чтобы какой-либо код мог устанавливать или перезаписывать эти поля.

Основываясь на моем поиске, я бы добавил .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) в конце .Property()?

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Doohicky>(entity =>
    {
        ... // other fields

        entity.Property(e => e.DateCreated).HasDefaultValueSql("(getdate())");

        ... // other fields
    });
}

Или я могу добавить аннотацию [DatabaseGenerated(DatabaseGeneratedOption.Identity)] в поле DateCreated?

public class Doohicky
{
    public DateTime DateCreated {get; set;}
}

Или есть другой способ полностью?

Я хочу, чтобы он был таким, чтобы вВ будущем, если кто-нибудь решит написать что-то подобное, возникнет ошибка.

model.DateCreated = new DateTime();
dbContext.SaveChanges() // errors out

Буду признателен за любую проницательность.

Ответы [ 3 ]

0 голосов
/ 04 января 2019

В прошлом я делал это с помощью проверяемых свойств, таких как DateCreated, DateModified и т. Д. Это решение, вероятно, не идеально для исключения определенных свойств в различных объектах (хотя вы, вероятно, могли бы что-то сделать с пользовательским атрибутом и т. Д.).).

Я переопределяю SaveChanges / Async (), затем перебираю все измененные объекты, которые отслеживает контекст.Все мои объекты используют один и тот же базовый класс, поэтому я могу добиться этого с помощью следующего:

var changes = ChangeTracker.Entries<BaseEntity>().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified);

С этими объектами я зацикливаюсь на них и устанавливаю некоторые проверяемые свойства или игнорирую определенные свойства, если объект не 'т новый.Во-первых, у меня есть коллекция строк, которые представляют имена свойств, которые я хочу исключить.Затем я перебираю коллекцию и игнорирую свойства, где имя свойства совпадает с именем исключенной коллекции.Смотрите ниже:

// A collection of property names which should not be updated
var excludedProperties = new[] { "CreatedBy", "CreatedDateUtc" };

foreach (var change in changes)
{
   // If new, do as you'd like

   // If used, ignore date created
   Array.ForEach(excludedProperties, prop =>
   {
      change.Property(prop).IsModified = false;
   });
}
0 голосов
/ 04 января 2019

Предполагаемый способ EF Core - установить для свойства AfterSaveBehavior значение, отличное от значения по умолчанию Сохранить :

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

Если Throw , то будет выдано исключение, если этому свойству будет присвоено новое значение после того, как сущность существует в базе данных.

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

Нет выделенного свободного APIтем не менее, вам нужно установить его напрямую через метаданные изменяемого свойства, например:

entity.Property(e => e.DateCreated)
    .HasDefaultValueSql("(getdate())")
    .Metadata.AfterSaveBehavior = PropertySaveBehavior.Throw; // <-- 
0 голосов
/ 04 января 2019
[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime DateCreated {get; set;}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...