Вызов Включить в Entity Framework Core 2.0 обнуляет сущность, если свойство, которое вы пытаетесь включить, равно нулю - PullRequest
0 голосов
/ 14 сентября 2018

Я получаю EF Core Entity, как это:

Audit audit = _auditRepo.Audits
            .Include(a => a.Status)
            .Include(a => a.AuditType)
            .Include(a => a.Office)
            .Include(a => a.LeadOffice)
            .Include(a => a.External)
            .Include(a => a.External).ThenInclude(e => e.AuditResult)
            .Include(a => a.External).ThenInclude(e => e.PreparerType)
            .Include(a => a.External).ThenInclude(e => e.Auditee)
            .Where(a => a.AuditID == id)
            .FirstOrDefault();

Мой аудит возвращается на ноль, потому что у него нет офиса.Если у меня есть офис, то аудит заполняется.

Если у меня нет офиса, но я комментирую:

.Include(a => a.Office) 

аудит также возвращается заполненным.

Вот мой объект Audit:

[Table("audit")]
public class Audit
{
    private string _auditAcnCd;
    private string _title;
    private string _summary;

    [Key]
    [Column("audit_id")]
    public int AuditID { get; set; }

    [Required(ErrorMessage = "ACN Required")]
    [Display(Name="ACN:")]
    [Column("audit_acn_cd")]
    public string AuditAcnCd
    {
        get
        {
            return _auditAcnCd;
        }
        set
        {
            _auditAcnCd = value?.Trim();
        }
    }

    [Required(ErrorMessage = "Title Required")]
    [Display(Name = "Title:")]
    [Column("audit_report_title_tx")]
    public string Title
    {
        get
        {
            return _title;
        }
        set
        {
            _title = value?.Trim();
        }
    }

    [StringLength(maximumLength: 1000, ErrorMessage = "Max Length: 1000")]
    [Display(Name = "Summary:")]
    [Column("audit_summary_tx")]
    public string Summary
    {
        get
        {
            return _summary;
        }
        set
        {
            _summary = value?.Trim();
        }
    }

    [Required(ErrorMessage = "Issuer Required")]
    [Display(Name="Issuer:")]
    [Column("audit_issuer_tx")]
    public string Issuer { get; set; }

    [RegularExpression("([1-9][0-9]*)", ErrorMessage = "Priority must be a number.")]
    [Display(Name = "Priority:")]
    [Column("audit_priority_cd")]
    public short? Priority { get; set; }

    [Display(Name = "Lead Office:")]
    [Column("audit_lead_office_id")]
    public short? LeadOfficeID { get; set; }

    #region Navigation Properties
    [Required(ErrorMessage = "Audit Type Required.")]
    [Display(Name = "Audit Type:")]
    [Column("audit_audit_type_id")]
    public short AuditTypeID { get; set; }
    [Display(Name = "Audit Type:")]
    public AuditType AuditType { get; set; }

    [Column("audit_status_id")]
    public int StatusID { get; set; } 
    public Status Status { get; set; }

    [Required(ErrorMessage = "Office is Required.")]
    [Display(Name = "Offices:")]
    [Column("audit_office_id")]
    public short? OfficeID { get; set; }
    // [ForeignKey("OfficeID")]
    public Office Office { get; set; }

    [ForeignKey("AuditID")]
    public External External { get; set; }

    public IEnumerable<AuditLog> AuditLogs { get; set; }
    public IEnumerable<Finding> Findings { get; set; }
    public IEnumerable<Assignment> Assignments { get; set; }

    [Column("audit_update_staff_id")]
    public short UpdateStaffID { get; set; }

    [Column("audit_fsa_office_id")]
    [Display(Name = "FSA Audit Lead:")]
    public int? FsaLeadOfficeId { get; set; }
    [Display(Name = "FSA Audit Lead:")]
    [ForeignKey("FsaLeadOfficeId")]
    public FSAOffice FsaLeadOffice { get; set; }

    [ForeignKey("LeadOfficeID")]
    public Office LeadOffice { get; set; }
}

Вот мой объект Office:

[Table("office")]
public class Office
{
    private string _OfficeCd;
    private string _OfficeNm;
    private string _OfficeOrganizationCd;

        [Key]
    [Column("office_id")]
    public short OfficeID { get; set; }

    [Required(ErrorMessage = "Numeric Code is required")]
    [StringLength(2, ErrorMessage = "Max Length is two")]
    [Display(Name = "Office Numeric Code:")]
    [Column("office_cd")]
    public string OfficeCd
    {
        get
        {
            return _OfficeCd;
        }
        set
        {
            _OfficeCd = value?.Trim();
        }
    }
    [Required(ErrorMessage = "Office Name is required")]
    [Display(Name = "Office Name:")]
    [Column("office_nm")]
    public string OfficeNm
    {
        get
        {
            return _OfficeNm;
        }
        set
        {
            _OfficeNm = value?.Trim();
        }
    }


    [Required(ErrorMessage = "Office Abbreviation is required")]
    [Display(Name = "Office Abbreviation:")]
    [Column("office_organization_cd")]
    public string OfficeOrganizationCd
    {
        get
        {
            return _OfficeOrganizationCd;
        }
        set
        {
            _OfficeOrganizationCd = value?.Trim();
        }
    }


    [Display(Name = "Status:")]
    [Column("office_active_cd")]
    public string OfficeActiveCd { get; set; }

    [Display(Name = "Parent Office:")]
    [Column("office_parent_id")]
    public short? OfficeParentId { get; set; }
    [Display(Name = "Parent Office:")] 
    [ForeignKey("OfficeParentId")]
    public Office ParentOffice { get; set; }

    public List<StaffOffice> StaffOffices { get; set; }
}

Все остальные мои свойства работают нормально.Нужно ли настроить это в onModelCreating?

1 Ответ

0 голосов
/ 14 сентября 2018

Объяснение простое - существует несоответствие между вашей моделью сущности и базой данных.

Когда FK обнуляется, как ваш OfficeId, связь необязательна, EF Core ожидает, что столбец может быть нулевым, и использует левое внешнее объединение при извлечении связанных данных (запрошено через Include ).

Но в какой-то момент вы, кажется, добавили атрибут [Required] к свойству FK:

[Required(ErrorMessage = "Office is Required.")] // <-- the problem
[Display(Name = "Offices:")]
[Column("audit_office_id")]
public short? OfficeID { get; set; }
// [ForeignKey("OfficeID")]
public Office Office { get; set; }

Обратите внимание, что атрибут [Required] и IsRequired() свободный API имеют приоритет над типом данных (конечно, вы не можете сделать необнуляемый тип обнуляемым, но возможен другой способ). В результате EF считает OfficeID FK обязательным (т. Е. Столбец без значения NULL в базе данных) и выполняет внутреннее объединение , что, конечно, фильтрует результат в случае, если запись содержит нулевое значение FK.

Решение состоит в том, чтобы удалить этот атрибут. И вообще, всегда синхронизируйте модель и базу данных. Каждый раз, когда вы что-то меняете в модели, добавляете новую миграцию Если он пуст, удалите его, в противном случае посмотрите, какие изменения в базе данных предполагаются EF на основе метаданных / конфигурации вашей модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...