我有一个典型的向下钻取应用程序。
这是我的应用程序的层次结构。
审核
有很多
结果
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
}
[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("recommend")]
public class Recommendation
{
private string _recText;
[Key]
[Column("recommend_id")]
public int RecommendationId { get; set; }
[Column("recommend_finding_id")]
public int RecFindingId { get; set; }
[Column("recommend_cd")]
public short? RecCd { get; set; }
[StringLength(7000)]
[Column("recommend_tx")]
public string RecText
{
get
{
return _recText;
}
set
{
_recText = value?.Trim();
}
}
[Column("recommend_contact_nm")]
public string RecContactName { get; set; }
[Column("recommend_status_id")]
public int RecStatusId { get; set; }
[Column("recommend_recommend_type_cd")]
public short? RecTypeCd { get; set; }
[Column("recommend_staff_id")]
public short RecStaffId { get; set; }
[Column("recommend_role_id")]
public short? RecRoleId { get; set; }
[Column("recommend_oig_decision_cd")]
public string RecOigDecisionCd { get; set; }
[Column("recommend_last_update_dt")]
public DateTime RecLastUpdateDt { get; set; }
[Column("recommend_action_determination_cd")]
public string RecActionDeterminationCd { get; set; }
#region Navigation Properties
[ForeignKey("RecFindingId")]
public Finding Finding { get; set; }
[ForeignKey("RecTypeCd")]
public RecommendationType RecommendationType { get; set; }
[ForeignKey("RecStatusId")]
public Status RecommendationStatus { get; set; }
[ForeignKey("RecStaffId")]
public Staff Staff { get; set; }
public List<Assignment> Assignments { get; set; }
#endregion
#region NOT Mapped
[NotMapped]
public string RecDisplayShortDesc => $"{RecCd} {RecText}";
#endregion
}
建议书可以有许多作业:
[Table("assignment")]
public class Assignment
{
[Key]
[Column("assignment_id")]
public int AssignmentId { get; set; }
[Column("assignment_role_id")]
public short AssignmentRoleId { get; set; }
[Column("assignment_type_cd")]
public string AssignmentTypeCd { get; set; }
[Column("assignment_dt")]
public DateTime AssignmentDate { get; set; }
[Column("assignment_by_staff_id")]
public short AssignmentByStaffId { get; set; }
[Column("assignment_recommend_id")]
public int? AssignmentRecommendId { get; set; }
[Column("assignment_office_id")]
public short? AssignmentOfficeId { get; set; }
#region Navigation Properties
[Column("assignment_staff_id")]
public short AssignmentStaffId { get; set; }
[ForeignKey("AssignmentStaffId")]
public Staff AssignmentStaff { get; set; }
[Column("assignment_audit_id")]
public int? AssignmentAuditId { get; set; }
[ForeignKey("AssignmentAuditId")]
public Audit Audit { get; set; }
[ForeignKey("AssignmentOfficeId")]
public Office AssignmentOffice { get; set; }
[ForeignKey("AssignmentRecommendId")]
public Recommendation Recommendation { get; set; }
#endregion
}
我有一个带有LINQ查询的View组件,使用Any()方法从顶级Audits集合一直向下来获取所有Audits,其中包含任何一个有推荐的结果,其中包含任何建议缺少角色ID为15或26的作业。如果rec中缺少其中一个或两个作业记录,那么应该将审核,审核,审核添加到审核集合中在模型中返回。
我们认为它似乎有效。但后来我们注意到,当审核中只有一个发现时,它没有被添加到集合中。只有当审计有很多调查结果并且其中一个调查结果发现缺少任务时,才会错误地添加审计。
这个foreach声明似乎对我有用:
// Where audit has a recommendation without an assigned PO Authorizer
// OR without an assigned Responsible Manager (Rec Level).
List<Audit> auditsToAssign = new List<Audit>();
foreach (Audit audit in audits)
{
foreach (Finding finding in audit.Findings)
{
foreach (Recommendation rec in finding.Recommendations)
{
if (!rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 15)
|| !rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 26)
)
{
if (!auditsToAssign.Contains(rec.Finding.Audit))
{
auditsToAssign.Add(rec.Finding.Audit);
}
}
}
}
}
但最初我试图写一个LINQ查询。 这已经过了很多次迭代,但这是目前的形式:
audits = audits.Where(a =>
a.Findings.Count() > 0 &&
a.Findings.Any(f =>
f.Recommendations.Count() > 0 &&
(
!f.Recommendations.Any(r =>
r.Assignments.Any(asgn => asgn.AssignmentRoleId == 15)) ||
!f.Recommendations.Any(r =>
r.Assignments.Any(asgn => asgn.AssignmentRoleId == 26))
)
)
);
答案 0 :(得分:2)
我并非100%确定我已按照您的说明操作,但请尝试以下操作:
audits = audits.Where(a =>
a.Findings.Any(f =>
f.Recommendations.Any(r =>
!r.Assignments.Any(asgn => asgn.AssignmentRoleId == 15 || asgn.AssignmentRoleId == 26))));
此外,Linq将比你的foreach更快,因为Any()方法一旦找到匹配就会停止枚举,而你的foreach将继续枚举整个集合,即使他们在一开始就找到匹配。它也更容易阅读恕我直言(虽然你开始使用它时需要一段时间才能让你的Linq眼睛进入)。
答案 1 :(得分:0)
我认为你可以更容易地反过来(假设你有一个完整的赋值表):
var auditsToAssign = assignments.Where(asgn => asgn.AssignmentRoleId != 15 && asgn.AssignmentRoleId != 26)
.Select(asgn => asgn.Recommendation.Finding.Audit)
.Distinct();