Chr☆s Kwok 的技术笔记

.NET, C#, WPF, WCF, WF, .NetCore & LINQ ... I know how it works because I know why it works ...

博客园 首页 新随笔 订阅 管理

1、譬如查询病历文书及其相关操作日志,数据传输对象类型DtoStrucDoc,DtoEncounter里的信息都是具有查询意义的,但是如果想增加一个“是否出院记录”的查询条件,就不知道往哪里放了。我们可以借助一个普通字典字段作为断言判断,前端勾选了就设置断言TRUE,否则是没这个断言或者FALSE。中间层方法可根据这个断言内容区分从而走不同的分支逻辑获取相关数据,又能使用通用查询IList<TEntity> GetByPredicate<TEntity, TKey>(this IQueryableRepository<TEntity, TKey> repository, PredicateSet predicates)

具体可参考如下代码:

    public class SurgeryDocLockedInfoCriterias : EntityCriterias, ISurgeryDocLockedInfoCriterias
    {
        public SurgeryDocLockedInfoCriterias()
        {
            this.ResponsibleDepartment = CriteriaHelper.NewObject<IStrucDoc, DtoStrucDoc, IOrganization>("所属科室", a => a.ResponsibleDepartment, a => a.ResponsibleDepartmentId, false).SetPickSource(OrganizationTreeKind.IPTreeKind.ValidDataProvider);
            this.SeqNoText = CriteriaHelper.NewString<IEncounter, DtoEncounter>("住院号", a => a.SeqNoText, a => a.SeqNoText);
            this.IsDischargedRecord = CriteriaHelper.NewBool<IClinicItem, DtoClinicItem>("是否出院记录", a => a.IsAllowMerge, a => a.IsAllowMerge);
        }
        public static readonly SurgeryDocLockedInfoCriterias Instance = new SurgeryDocLockedInfoCriterias();
        public IObjectCriteria<IStrucDoc, IOrganization> ResponsibleDepartment
        {
            get;
            set;
        }
        public IStringCriteria<IEncounter> SeqNoText
        {
            get;
            set;
        }
        public IBoolCriteria<IClinicItem> IsDischargedRecord
        {
            get;
            set;
        }
    }

在前端根据界面条件或特定属性复制Criterias

    private IList<ISurgeryDocLockedInfo> _items;
    private void ExecRefresh()
    {
        PredicateSet predicates = new PredicateSet();
        var criterias = Repository.Criterias;

        if (!string.IsNullOrEmpty(_queryContext.IPSeqNotext))
        {
            predicates.Add(criterias.SeqNoText.Equal(_queryContext.IPSeqNotext));
        }
        if (_queryContext.ResponsibleDepartments != null && _queryContext.ResponsibleDepartments.Count() > 0)
        {
            predicates.Add(criterias.ResponsibleDepartment.Contains(_queryContext.ResponsibleDepartments.ToArray()));
        }
        predicates.Add(criterias.IsDischargedRecord.Equal(IsDischargedRecord));
        using (MessageHelper.PopupWait("正在加载..."))
        {
            _items = Repository.GetByPredicate(predicates);
            this.View.SetSurgeryDocLockedInfos(_items.OrderByDescending(a => a.OperationOn).ToList());
        }
    }

最后,回到中间层具体处理来自这个“特殊角色”的条件,我们知道勾选了该条件,其内容就是"a => (a.IsAllowMerge == True)":

    public IList<DtoSurgeryDocLockedInfo> GetSurgeryDocLockedInfo(ClientContext context, PredicateCollection predicates)
    {
        //特别注意:借用断言(a.IsAllowMerge == True/False)获取前端查询条件“是否查询出院记录”
        Expression<Func<DtoClinicItem, bool>> isChargedRecordFilter = predicates.Get<DtoClinicItem>();
        bool isDischargedRecord = (isChargedRecordFilter.ToString() == "a => (a.IsAllowMerge == True)") ? true : false;
        if (isDischargedRecord)
            return DoGetDischargedDocLockedInfo(context, predicates);
        else
            return DoGetSurgeryDocLockedInfo(context, predicates);
    }

 2、IN 子句的 ID 串过多需要使用上下文表自然连接进行性能改善代码范例:

public IList<DtoMedicalRecordMonitorCreated> GetMedicalRecordMonitorCreatedByPara(ClientContext context, Dbs dbs, ReportSvcParameters para)
{
	var items = new List<DtoMedicalRecordMonitorCreated>();
	int queryContextId = -1;
	DateTime beginDate = para.BeginDate.Value.Date;
	DateTime endDate = para.EndDate.Value.Date.AddDays(1);

	Expression<Func<DtoMedicalRecordMonitorCreated, bool>> expr = a => true;
	ServerContext sc = this.CreateContext(context);

	expr = expr.And(a => a.AdmitDateOn >= beginDate && a.AdmitDateOn < endDate);
	if (para.OrganizationIds != null && para.OrganizationIds.Count > 0)
	{
		if (para.OrganizationIds.Count > 50)
			queryContextId = sc.SaveCisQueryContext(para.OrganizationIds.ToArray());
		else
			expr = expr.And(a => para.OrganizationIds.Contains(a.Organizationid));
	}

	try
	{
		using (var edm = sc.CreateEdm<EdmReport>(Dbs.His))
		{
			if (queryContextId == -1)
				items = edm.MedicalRecordMonitorCreateds.Where(expr.Shrink()).ToList();
			else
				items = edm.MedicalRecordMonitorCreateds.Where(expr)
						.Join(edm.Query<DtoCisQueryContextIdentity>().Where(a => a.QueryContextId == queryContextId), a => a.Organizationid, a => a.Identity, (a, b) => a).ToList();

		}

	}
	catch (Exception ex)
	{
		sc.HandleException(ex);
	}

	return items;
}

 3、自然连接(内连接)JOIN 的用法范例:

//特别注意:借用断言(a.IsAllowMerge == True/False)获取前端查询条件“是否仅查询在院记录”
Expression<Func<DtoClinicItem, bool>> isOnlyInHospitalFilter = predicates.Get<DtoClinicItem>();
bool isOnlyInHospital = (isOnlyInHospitalFilter != null && isOnlyInHospitalFilter.ToString() == "a => (a.IsAllowMerge == True)");

Expression<Func<DtoAntibacterialConsultation, bool>> consultationFilter = predicates.Get<DtoAntibacterialConsultation>();
Expression<Func<DtoAntibacterialConsultationItem, bool>> itemFilter = predicates.Get<DtoAntibacterialConsultationItem>();
IQueryable<DtoAntibacterialConsultation> query = edm.AntibacterialConsultations.Include(a => a.Items).Where(consultationFilter);
if (isOnlyInHospital)
{
	ObjectQuery<DtoEncounter> qryEnc = edm.Query<DtoEncounter>();
	query = query.Join(qryEnc.Where(a => a.IsDeleted == false && (a.StatusCodeId == 1 || a.StatusCodeId == 2)), a => a.EncounterId, b => b.EncounterId, (a, b) => a);
}
if (itemFilter != null)
{
	query = query.Join(edm.AntibacterialConsultationItems.Where(itemFilter).Select(a => a.AntibacterialConsultationId), a => a.AntibacterialConsultationId, a => a, (a, b) => a) as ObjectQuery<DtoAntibacterialConsultation>;
}

list = query.Distinct().ToList();

 

posted on 2025-11-13 15:43  Chr☆s  阅读(14)  评论(0)    收藏  举报