Entity framework core 实体框架不保存一个实体类型上一个属性的更新

Entity framework core 实体框架不保存一个实体类型上一个属性的更新,entity-framework-core,asp.net-core-mvc-2.0,Entity Framework Core,Asp.net Core Mvc 2.0,我正在Visual Studio 2017中使用ASP.Net核心MVC和实体框架核心 我们使用的是一种非常直接的存储库模式 我在这个项目中工作了八个月,这是我第一次在这个实体的这个属性上遇到这种奇怪的问题,在UpdateChanges之后在SaveChanges上保存到数据库 这就是流程 1) 我有一个创建控制器操作来保存一个名为Recommension的新实体。 该建议有一个名为finding的父实体。 创建新建议时,我必须更新父项查找的状态。此外,查找实体还有一个名为Audit的父实体。

我正在Visual Studio 2017中使用ASP.Net核心MVC和实体框架核心

我们使用的是一种非常直接的存储库模式

我在这个项目中工作了八个月,这是我第一次在这个实体的这个属性上遇到这种奇怪的问题,在UpdateChanges之后在SaveChanges上保存到数据库

这就是流程

1) 我有一个创建控制器操作来保存一个名为Recommension的新实体。 该建议有一个名为finding的父实体。 创建新建议时,我必须更新父项查找的状态。此外,查找实体还有一个名为Audit的父实体。 编辑查找状态时,我还必须更新审核状态

下面是一些代码

[HttpPost]
public IActionResult Create(CreateIntRecommendationVM createIntRecommendationVM)
{
    int findingId = createIntRecommendationVM.Finding.FindingId;
        Finding finding = _findingRepo.Findings
            .Include(f => f.Audit)
            .Where(f => f.FindingId == findingId)
            .FirstOrDefault();

    if (RecModelStateIsValid(ModelState))
        {
            ClaimsPrincipal user = HttpContext.Request.HttpContext.User;
            short staffId = short.Parse(user.Claims.Single(c => c.Type == "StaffId").Value);

            Recommendation recommendation = createIntRecommendationVM.Recommendation;
            recommendation.RecFindingId = findingId;

            #region Get Recommendation Number
            recommendation.RecCd = GetRecommendationNumber(findingId);
            #endregion

            recommendation.RecStatusId = 10;
            recommendation.RecStaffId = staffId;
            recommendation.RecLastUpdateDt = DateTime.Now;

            _recommendationRepo.Add(recommendation);
            _recommendationRepo.SaveChanges();

            bool unresolvedFinding = false;
            bool unresolvedAudit = false;
            int? oldFindingStatus = finding.FindingStatusId;
            if (finding.FindingStatusId != 10)
            {
                finding.FindingStatusId = 10;
                unresolvedFinding = true;
            }
            if (oldFindingStatus != 10 && finding.Audit.StatusID != 10)
            {
                finding.Audit.StatusID = 10;
                unresolvedAudit = true;
            }

            _findingRepo.Update(finding);
            _findingRepo.SaveChanges();
当我在调试模式下运行并在单步执行时放置断点并进行检查时,我会将finding.FindingStatusId设置为10,finding.Audit.StatusID设置为10

_findingRepo.Update(finding);
点击本回购协议:

public class FindingRepository : IFindingRepository
    {
        private ApplicationDbContext context;
        public FindingRepository(ApplicationDbContext ctx)
        {
            context = ctx;
        }

        public IQueryable<Finding> Findings => context.Findings;

        public Finding Get(int id)
        {
            Finding finding = context.Findings.Find(id);
            return finding;
        }

        public void Add(Finding finding)
        {
            context.Findings.Add(finding);
        }

        public void Update(Finding finding)
        {
            context.Findings.Update(finding);
        }

        public void Delete(int id)
        {
            context.Database.ExecuteSqlCommand("sp_delete_finding_int @finding_id = {0}", id);
        }

        public void SaveChanges()
        {
            context.SaveChanges();
        }
    }
公共类查找存储库:IFindingRepository
{
私有应用程序上下文上下文;
公共查找存储库(ApplicationDbContext ctx)
{
上下文=ctx;
}
公共IQueryable结果=>context.Findings;
公共查找Get(int-id)
{
Finding=context.Findings.Find(id);
回归发现;
}
公共空白添加(查找)
{
上下文。发现。添加(发现);
}
公共无效更新(查找)
{
背景。调查结果。更新(调查结果);
}
公共无效删除(int-id)
{
ExecuteSqlCommand(“sp_delete_finding_int@finding_id={0}”,id);
}
公共void SaveChanges()
{
SaveChanges();
}
}
这就是奇怪的部分。 正在数据库中更新finding.Audit.StatusID。 finding.FindingStatusId不可用

因此,对于我发送给回购协议更新方法的实体“finding”,正在更新的实体的“FindingStatusId”不会被保存。 但是,正在保存“查找”实体的父级“审核”和“状态ID”

我一辈子都搞不清楚这里发生了什么

为了完整性,我将发布查找和审计实体模型

[Table("finding")]
    public class Finding
    {
        private string _findingText;

        [Key]
        [Column("finding_id")]
        public int FindingId { get; set; }

        [Column("finding_audit_id")]
        public int FindingAuditId { get; set; }

        [Column("finding_cd")]
        [Display(Name = "Finding #")]
        [StringLength(15)]
        public string FindingCd { get; set; }

        [Column("finding_tx")]
        [Required(ErrorMessage = "Description Required")]
        [StringLength(7000)]
        public string FindingText
        {
            get
            {
                return _findingText;
            }
            set
            {
                _findingText = value?.Trim();
            }
        }

        [Column("finding_page_cd")]
        [StringLength(100)]
        public string FindingPageCd { get; set; }

        [Column("finding_joint_cd")]
        public string FindingJointCd { get; set; }

        [Column("finding_compliance_tx")]
        [StringLength(20)]
        public string FindingComplianceText { get; set; }

        [Column("finding_prior_year_cd")]
        [Display(Name = "Repeat Finding")]
        public string FindingPriorYearCd { get; set; }

        [Column("finding_decision_cd")]
        public string FindingDecisionCd { get; set; }

        [Column("finding_request_decision_cd")]
        public string FindingRequestDecisionCd { get; set; }

        [Column("finding_decision_ogc_concur_cd")]
        public string FindingDecisionOgcConcurCd { get; set; }

        [Column("finding_pdl_id")]
        public int? FindingPdlId { get; set; }

        [Display(Name = "Significant")]
        [Column("finding_significant_cd")]
        public string FindingSignificantCd { get; set; }

        [Column("finding_on_stay_cd")]
        public string FindingOnStayCd { get; set; }

        [Column("finding_stay_request_cd")]
        public string FindingStayRequestCd { get; set; }

        [Column("finding_last_update_dt")]
        public DateTime FindingLastUpdateDate { get; set; }

        [Column("finding_update_staff_id")]
        public short? FindingUpdateStaffId { get; set; }

        [Column("finding_cd_org")]
        public string FindingCdOrg { get; set; }

        [NotMapped]
        public string RepeatingYearsDisplayList
        {
            get
            {
                if (RepeatingYears?.Count > 0)
                {
                    string repeatingYears = string.Empty;
                    RepeatingYears.ForEach(ry =>
                        repeatingYears += $"{ry.FindingFyCd}, ");
                    return repeatingYears.Remove(repeatingYears.Length - 2);
                }
                return string.Empty;
            }
        }

        #region Navigation Properties
        [Column("finding_finding_type_id")]
        public short? FindingTypeId { get; set; }
        [ForeignKey("FindingTypeId")]
        public FindingType FindingType { get; set; }

        [Column("finding_status_id")]
        public int? FindingStatusId { get; set; }
        [ForeignKey("FindingStatusId")]
        public Status FindingStatus { get; set; }

        public List<FindingFiscalYear> RepeatingYears { get; set; }
        public List<Recommendation> Recommendations { get; set; }

        [ForeignKey("FindingAuditId")]
        public Audit Audit { get; set; }
        #endregion
    }



[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();
            }
        }

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

        [Display(Name = "Sensitive Designation")]
        [Column("audit_sensitive_cd")]
        public string AuditSensitiveCode { get; set; }

        [Display(Name = "Alternative Product")]
        [Column("audit_alternate_product_cd")]
        public string AuditAlternateProductCode { 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; }

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

        [Column("audit_gao_contact_tx")]
        [Display(Name = "GAO Contact:")]
        [StringLength(maximumLength: 200, ErrorMessage = "Max Length: 200")]
        public string AuditGaoContactText { get; set; }

        [Column("audit_gao_job_cd")]
        [Display(Name = "GAO Job Code:")]
        [StringLength(maximumLength: 200, ErrorMessage = "Max Length: 30")]
        public string AuditGaoJobCode { 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; }
        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_oig_manager_id")]
        [Display(Name = "OIG Audit Manager:")]
        public short? OigAuditManagerId { get; set; }
        [Display(Name = "OIG Audit Manager:")]
        [ForeignKey("OigAuditManagerId")]
        public Staff OigAuditManager { 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; }
        #endregion
    }
[表(“查找”)]
公共类查找
{
私有字符串_findingText;
[关键]
[列(“查找id”)]
public int FindingId{get;set;}
[列(“查找审计id”)]
public int findingAudited{get;set;}
[栏目(“查找光盘”)]
[显示(Name=“Finding#”)]
[第15段]
公共字符串查找CD{get;set;}
[列(“查找结果”)]
[必需(ErrorMessage=“Description Required”)]
[长度(7000)]
公共字符串查找文本
{
得到
{
返回_findingText;
}
设置
{
_findingText=值?.Trim();
}
}
[栏目(“查找页面光盘”)]
[长度(100)]
公共字符串查找页面CD{get;set;}
[专栏(“发现联合光盘”)]
公共字符串查找jointcd{get;set;}
[列(“发现合规性”)]
[行政长官(20)]
公共字符串查找符合性文本{get;set;}
[栏目(“发现上一年光盘”)]
[显示(Name=“重复查找”)]
公共字符串查找优先级earcd{get;set;}
[专栏(“调查结果决定cd”)]
公共字符串查找决策CD{get;set;}
[列(“查找请求决定cd”)]
公共字符串查找RequestDecisionCD{get;set;}
[栏目(“调查结果决定”ogc concur_cd)]
公共字符串查找DecisionOGCConCurcD{get;set;}
[列(“查找pdl\U id”)]
公共int?FindingPdlId{get;set;}
[显示(Name=“重要”)]
[栏目(“发现重要cd”)]
公共字符串查找有效CD{get;set;}
[栏目(“在光盘上查找”)]
公共字符串查找onstaycd{get;set;}
[栏目(“查找、保留、请求、光盘”)]
公共字符串查找StayRequestCD{get;set;}
[列(“查找上次更新”)]
公共DateTime FindingLastUpdateDate{get;set;}
[栏(“查找更新员工id”)]
public short?FindingUpdatesAffid{get;set;}
[栏目(“查找光盘组织”)]
公共字符串查找cdorg{get;set;}
[未映射]
公共字符串重复年份显示列表
{
得到
{
如果(重复年数?.Count>0)
{
string repeatingYears=string.Empty;
重复年份。ForEach(ry=>
repeatingYears+=$”{ry.FindingFyCd},”;
返回repeatingYears.Remove(repeatingYears.Length-2);
}
返回字符串。空;
}
}
#区域导航属性
[列(“查找类型id”)]
公共short?FindingTypeId{get;set;}
[ForeignKey(“FindingTypeId”)]
公共查找类型查找类型{get;set;}
[列(“查找状态id”)]
public int?FindingStatusId{get;set;}
[ForeignKey(“FindingStatusId”)]
公共状态查找状态{get;set;}
公共列表重复年份{get;set;}
公共列表建议{get;set;}
[外键(“FindingAudid”)]
公共审计{get;set;}
#端区
}
[表(“审计”)]
公开课审计
{
私有字符串\u auditAcnCd;
私有字符串\u标题;
私有字符串\u摘要;
[关键]
[列(“审计id”)]
公众智力测验