我在nhibernate中有这个查询
var fdata = (from p in _session.Query<WfTask>()
join d in _session.Query<WfTaskDetail>() on p.WfTaskDetail.Id equals d.Id
orderby p.ActionDate descending //(order)
where
(_session.Query<WfTask>().Any(x => x.Actor.Id == personid && x.Action != null
&& x.Action.Id == actionDic[statusId] && p.Id != x.Id && p.WfTaskDetail.Id==x.WfTaskDetail.Id && p.StepNo>=x.StepNo-1) || (p.Actor.Id == personid && p.Status == statusId && p.StepNo==1))
&& p.Owner.Id == personid && (actorId == new Guid() || p.Actor.Id == actorId)
select new DataList
{
WfTask = p,
Name = userService.GetFullName(p.Actor.Id),
PositionName = org.GetOrganizatinOfPerson(p.Actor.Id).Name,// p.PositionName
//Statusid = new Guid(),//grp.Where(x => x.WfTask.StepNo == maxStepNo && x.WfTask.DocId == p.WfTask.DocId).Select(x => x.WfTask.Status).FirstOrDefault(),
Actionid = actionDic[statusId]
});
total = fdata.Count();
var dataa = pageNumber > 0 ? fdata.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList() : fdata.Take(pageSize).ToList();
问题是执行查询的时间非常长。 我该如何解决这个问题?
模型和映射:
public class WfTask
{
public virtual Guid Id { get; set; }
public virtual Person Owner { get; set; }
public virtual Person Actor { get; set; }
public virtual Guid DocId { get; set; }
public virtual int StepNo { get; set; }
public virtual Guid WfInstanceId { get; set; }
public virtual Guid OwnerGroupId { get; set; }
public virtual Guid Status { get; set; }
public virtual Guid WfActionId { get; set; }
public virtual Guid WfStateId { get; set; }
public virtual Guid OwnerId { get; set; }
public virtual Guid ActorId { get; set; }
public virtual Guid WfTaskDetailId { get; set; }
public virtual string Comment { get; set; }
public virtual DateTime ActionDate { get; set; }
public virtual WfAction Action { get; set; }
public virtual WfState WfState { get; set; }
public virtual WfTaskDetail WfTaskDetail { get; set; }
public virtual bool ViewState { get; set; }
public virtual bool Deleted { get; set; }
}
public WfTaskMap()
{
Table("WfTask");
Id(m => m.Id).Column("Id");
Map(m => m.WfInstanceId);
Map(m => m.OwnerGroupId);
Map(m => m.Status);
Map(m => m.DocId);
Map(m => m.StepNo);
Map(m => m.Comment).Length(500);
Map(m => m.ActionDate);
References(x => x.Action).Column("WfActionId").Cascade.All();
References(x => x.WfState).Column("WfStateId").Cascade.All();
References(x => x.WfTaskDetail).Column("WfTaskDetailId").Cascade.All();
References(x => x.Owner).Column("OwnerId").ForeignKey("FK_Person_WfTask_OwnerId").Cascade.All();
References(x => x.Actor).Column("ActorId").ForeignKey("FK_Person_WfTask_ActorId").Cascade.All();
Map(m => m.ViewState);
Map(m => m.Deleted);
}
public class WfTaskDetail:IModel
{
public virtual Guid Id { get; set; }
public virtual Guid DocId { get; set; }
public virtual string Description { get; set; }
public virtual string Subject { get; set; }
public virtual string Type { get; set; }
public virtual Guid OrgVersionId { get; set; }
public virtual Guid WfVersionId { get; set; }
public virtual Guid DocTypeId { get; set; }
public virtual DateTime CreatedDate { get; set; }
public virtual WfVersion WfVersion { get; set; }
public virtual WfDocType DocType { get; set; }
}
public WfTaskDetailMap()
{
Table("WfTaskDetail");
Id(m => m.Id).Column("Id");
Map(m => m.DocId);
Map(m => m.Description).Length(1000);
Map(m => m.Subject).Length(1000);
Map(m => m.Type).Length(1000);
Map(m => m.OrgVersionId);
Map(m => m.CreatedDate);
References(x => x.DocType).Column("DocTypeId").Cascade.All();
References(x => x.WfVersion).Column("WfVersionId").Cascade.All();
}
我在sql server中运行此查询,它会快速执行 我还想知道是否有办法用nhibernate标准编写查询。
答案 0 :(得分:0)
由于我们不了解您的架构和映射,因此我们无法有效地帮助您 我建议你更简单,并将linq查询转换为sql查询并运行它 如果运行时是等于的,则意味着您需要在数据库上创建更好的索引或将查询分成2个或更多查询。
如果没有,这意味着您编写的linq查询无法满足您的实际需求,因此您必须重新构建它。
答案 1 :(得分:0)
你有NHibernate生成的SQL输出吗?它是一大堆SQL查询还是一个大查询?
使用LINQ .Count(),如
total = fdata.Count();
在具有延迟执行的IEnumerable上的总是很糟糕,因为它实际上通过解析表达式(可能具有DB访问权限)来计算,而不是像List.Count那样返回已知数量的项目;或者Array.Length会这样做。