实体框架不会仅针对一种实体类型的一种属性保存更新

时间:2018-08-10 21:43:18

标签: entity-framework-core asp.net-core-mvc-2.0

我正在Visual Studio 2017中使用ASP.Net Core MVC和Entity Framework Core。

我们正在使用非常简单的存储库模式。

我已经进入这个项目八个月了,这是我第一次对这个实体的一个属性遇到这个奇怪的问题,该实体在UpdateChanges之后通过SaveChanges保存到数据库中。

这是流程。

1)我有一个Create controller动作来保存一个称为Recommendation的新实体。 该建议书有一个称为发现的上级实体。 创建新建议时,我必须更新父调查结果的状态。查找实体还具有一个称为审计的父实体。 在编辑查找状态时,我还必须更新审核状态。

这是一些代码。

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

当我在调试模式下运行并设置一个断点并在逐步检查时,我一定要将find.FindingStatusId设置为10,并将find.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();
        }
    }

这是奇怪的部分。 find.Audit.StatusID在数据库中正在更新。 find.FindingStatusId不是。

因此,对于该实体,我发送到存储库的Update方法的“查找”,没有保存要更新的实体的“ FindingStatusId”。 但是,“查找”实体的父级“审计”,“ StatusID”正在保存。

我无法终生弄清这里发生的事情。

为完整起见,我将发布“查找和审计实体模型”。

[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
    }

1 个答案:

答案 0 :(得分:1)

好吧,就像我希望今天早上将其重新打开,重新开始,并且可以正常工作。

伊万,我相信你是对的。您无需调用实体框架的更新。如果我忘记了Update语句,我之前已经注意到这一点。

如果不需要,您会无缘无故地打电话给仓库中的更新。

我正在数据库中手动重置场景以反复测试。某些东西一定已经腐败了。

但是上面的所有代码都可以帮助任何人。