我正在获得这样的EF核心实体:
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)
审核也重新填充。
这是我的审核单位:
[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
中进行配置?
答案 0 :(得分:2)
解释很简单-您的实体模型和数据库之间存在差异。
当FK像您的OfficeId
一样可为空时,该关系是可选的,EF Core希望该列可以为空,并在检索相关数据时使用 left external join (通过Include
。
但是在某些时候,您似乎向FK属性添加了[Required]
属性:
[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是必需的(即数据库中不可为空的列)并执行内部联接,这当然会过滤如果记录包含空FK值,则返回结果。
解决方案是删除该属性。通常,始终保持模型和数据库同步。每当您更改模型中的某些内容时,请添加新的迁移。如果它是空的,请将其删除,否则请根据模型元数据/配置查看EF假定的数据库更改。