为了账号安全,请及时绑定邮箱和手机立即绑定

对HasMany引用的查询

对HasMany引用的查询

C#
胡说叔叔 2019-07-17 18:49:04
对HasMany引用的查询我有一个这样的实体模型:public class Request{     public virtual IList<Response> Responses { get; set; }}public class Response{     public virtual DateTime Timestamp { get; set; }     public virtual bool Success { get; set; }}我想创造一个查询那会给我所有请求最近反应(关于其时间戳)是成功..这是如何做到的呢?
查看完整描述

3 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

差不多了一直以来,NHibernate确实对此有答案。我们在这里试图实现的是这样一个SQL语句:

// final Request selectionSELECT request.[RequestId] 
 FROM [Request] request 

   // Only requests, which are successful, and have Max(date)
   WHERE request.[RequestId] IN 
   (
     SELECT successResponse.RequestId as y0_ 
      FROM [Response] successResponse 

        // response which max date is equal to the upper response
        // and which RequestId corresponds with supper upper Request
        WHERE EXISTS        (
          SELECT maxResponse.RequestId as y0_           , max(maxResponse.[DateTime]) as y1_           
           FROM [Response] maxResponse 

           // do the MAX only for current Request
           WHERE maxResponse.RequestId = successResponse.RequestId 
           GROUP BY maxResponse.RequestId 

           // assure that the Response match is on the max DateTime
           HAVING max(maxResponse.[DateTime]) = successResponse.[DateTime]
        ) 
        AND successResponse.[Success] = 1
   )

注:

  1. 期待

    反应  RequestId

  2. 上面用的是C#//注释而不是SQL--

现在,NHibernate和QueryOver的魔力:

// This declaration will allow us, to use a reference from middle SELECT// in the most deeper SELECTResponse response = null;// the most INNER SELECTvar maxSubquery = QueryOver.Of<Response>()
   .SelectList(l => l    .SelectGroup(item => item.RequestId)
    .SelectMax(item => item.DateTime)
    )
    // WHERE Clause
   .Where(item => item.RequestId == response.RequestId)
   // HAVING Clause
   .Where(Restrictions.EqProperty(
      Projections.Max<Response>(item => item.DateTime),
      Projections.Property(() => response.DateTime)
    ));// the middle SELECTvar successSubquery = QueryOver.Of<Response>(() => response)
    // to filter the Request
    .Select(res => res.RequestId)
    .WithSubquery
    .WhereExists(maxSubquery)
    // now only these wich are successful
    .Where(success => success.Success == true)
    ;

此时我们不得不对内子进行选择,嵌套。让我们使用它们:

// the most outer SELECTvar query = session.QueryOver<Request>();query.WithSubquery
    // our Request ID is IN(...
    .WhereProperty(r => r.ID)
    .In(successSubquery);var list = query    .List<Request>();

最后,我不是在讨论这个概念。不是表演。我会使用一个关于响应“IsActive”的设置,使它更容易..这就是该怎么做的答案.。


查看完整回答
反对 回复 2019-07-17
?
Cats萌萌

TA贡献1805条经验 获得超9个赞

我要试试这个,这里有一些Linq(使用Query)。

session.Query<Request>()
    .Where(request => 
        request.Responses.Count() > 0 && 
        request.Responses.OrderByDescending(response => response.Timestamp)
                         .First()
                         .Success);

不知道这是否行得通。


查看完整回答
反对 回复 2019-07-17
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

SelectList表示投影,即我们要返回的一组列/公式。因此,非常深的SELECT必须返回2个值,这些值用于上层查询。(寻找匹配的记录)..可能会吧.Select()带着帕拉姆我也要说.。在子查询中使用get(1)在这种情况下不起任何作用。DB引擎将创建正确的执行计划,一旦找到匹配。它会停止的。因此,在这个层面上,它是不需要的。如果我完全理解你的观点。总之,我们的任何优化,帮助DB引擎.。(可受欢迎;) 

查看完整回答
反对 回复 2019-07-17
  • 3 回答
  • 0 关注
  • 621 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信