【问题标题】:time of executing query nhibernate执行查询休眠的时间
【发布时间】:2013-10-30 08:27:15
【问题描述】:

我在 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 条件中编写查询。

【问题讨论】:

  • - 你似乎没有使用...join d in...。将actionDic[statusId] 替换为应在运行查询之前设置的变量。 actorId == new Guid() 是什么意思? Name 和 PositionName 应该涉及处理。它们不应出现在选择中,因为它们仅对当前页面上显示的信息有用。

标签: sql nhibernate nhibernate-mapping linq-to-nhibernate nhibernate-criteria


【解决方案1】:

由于我们不知道您的架构和映射,我们无法有效地帮助您。
我建议您更简单,将 linq 查询转换为 sql 查询并运行它。
如果运行时相等,则意味着您可能需要在数据库上创建更好的索引或将查询划分为 2 个或更多查询。

如果不是,说明你写的 linq 查询不能满足你的实际生活需要,所以你必须重新构建它。

【讨论】:

    【解决方案2】:

    你有 NHibernate 生成的 SQL 输出吗?是一大堆 SQL 查询,还是一个大查询?

    像使用 LINQ .Count() 一样

    total = fdata.Count();
    

    在延迟执行的 IEnumerable 上总是不好的,因为它确实通过解析表达式(可能使用 DB 访问)来计算,而不是返回已知数量的项目,如 List.Count;或 Array.Length 可以。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-06
      • 2016-11-22
      • 1970-01-01
      • 2012-05-19
      • 2014-01-26
      相关资源
      最近更新 更多