Могу ли я следить за свойством за изменениями без использования специального средства доступа? - PullRequest
1 голос
/ 25 апреля 2020

Entity Framework Core не нравится, когда я использую пользовательский аксессор набора для свойства навигации виртуального внешнего ключа с включенной отложенной загрузкой. Выдает исключительную ситуацию во время запуска / конфигурации. Я хотел бы запускать некоторый пользовательский код каждый раз, когда установлено одно из этих свойств. Можно ли как-нибудь это сделать, чтобы EF Core не кричал на меня? Примеры кода / пояснения ниже:

public class CoilUnit
{
    [Key]
    public Guid Id { get; set; }

    [ForeignKey("project")]
    public virtual CoilProject Project { get; set; }
}
public class CoilProject
{
    [Key]
    public Guid Id { get; set; }
}

Вышеприведенная установка прекрасно работает в EF Core, но она не выполняет то, что я хочу.

Вот что Я хочу:

public class CoilUnit
{
    [Key]
    public Guid Id { get; set; }

    private CoilProject project;

    [ForeignKey("project")]
    public virtual CoilProject Project
    {
        get { return project; }
        set { project = value; /* Other code here */ }
    }
}
public class CoilProject
{
    [Key]
    public Guid Id { get; set; }
}

С точки зрения кода это делает то, что я хочу, но EF Core не нравится и не запускается, когда я делаю это.

Есть ли способ в этой ситуации взять мой пирог и съесть его тоже? Есть ли способ заставить /* Other Code */ работать должным образом, и при этом дать EF Core свой путь?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 25 апреля 2020

Эта проблема не имеет ничего общего с отложенной загрузкой и установщиком настраиваемых свойств, но конфликт между полем поддержки и именами свойств теневого FK.

При применении к свойству навигации атрибут ForeignKey указывает свойство FK имя. Если такого свойства не существует, EF Core создаст теневое свойство с этим именем.

С авто-свойством вспомогательное поле name генерируется компилятором и является не "project", так что нет проблем. Но во втором случае уже есть поле с именем "project", поэтому EF Core решает, что это свойство FK, указанное атрибутом. Но, конечно, это не так, и также не является ожидаемым типом (Guid или Guid?), следовательно, исключение.

Если вы использовали обычные имена свойств / столбцов FK (например, ProjectId) ), вам не понадобится этот атрибут, и у вас не будет проблем. Я уверен, что вас не заботит имя теневого свойства, а имя столбца таблицы.

Таким образом, один из способов решения этой проблемы - удалить атрибут ForeignKey и использовать свободный API для настройки имени столбца FK:

private CoilProject project;

public virtual CoilProject Project
{
    get { return project; }
    set { project = value; /* Other code here */ }
}

и

modelBuilder.Entity<CoilUnit>()
    .Property<Guid?>(nameof(CoilUnit.Project) + "Id")
    .HasColumnName("project");

Другой способ - сохранить атрибут, но переименовать поле поддержки свойства навигации в один из других поддерживаемых шаблонов , например "_project":

private CoilProject _project;

[ForeignKey("project")]
public virtual CoilProject Project
{
    get { return _project; }
    set { _project = value; /* Other code here */ }
}
1 голос
/ 25 апреля 2020

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

public class CoilUnit
{
    [Key]
    public Guid Id { get; set; }

    private CoilProject project;

    [ForeignKey("project")]
    public virtual CoilProject Project { get; set; }

    [NotMapped]
    public virtual CoilProject ProjectNotMapped
    {
        get { return project; }
        set { project = value; /* Other code here */ } 
    }
}

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

        public virtual CoilProject ProjectNotMapped
        {
            set { project = value; /* Other code here */ } 
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...