实体框架具有日期,分组依据和计数的多个联接类型

时间:2015-09-25 19:46:25

标签: c# sql-server entity-framework

我有一个由3个表组成的聊天系统:Users,RoomJoins(已加入的私人会议室)和Chats(带时间戳的聊天消息列表)。

我希望得到一个给定用户的所有私人房间列表,然后是他上次登录后收到的新聊天消息的数量。

有效的sql查询(可能可以改进,但肯定有效)是:

select a.roomid, b.userid, m.firstpicurl, count(p.roomid) as cuenta from roomjoin a
 inner join roomjoin b
on b.roomid=a.roomid and a.userid<>b.userid
inner join myuser m on m.id=b.userid
 left join
 chat p on p.roomid=a.roomid and p.sentwhen > a.lastseen
 where a.userid=45 and a.active=1
  group by a.roomid, b.userid, m.firstpicurl

基本上说:为userid = 45给我所有的房间(私人谈话),也是发给我信息的人的用户ID,他的照片以及发送时的聊天消息的数量&gt; user.lastseen

结果将类似于

roomid  userid  firstpicurl  cuenta
1        43     http://...     3
2        37     http://...     0

意味着自上次登录以来,用户ID 43已向您发送了3条消息,而用户37并未向您发送任何新消息

现在,我尝试将其转换为EF并且我有点工作,但问题是我找不到使用sentwhen&gt;查询的方法。最后的日期格式,因为它不允许这样做。如果我尝试Where子句,我永远得不到正确的答案。这是我现有的尝试(没有发送&gt; lastseen)

from a in db.RoomJoins.Where(c => c.userid == u.id && c.active == true).OrderBy(c => c.roomid)
                                 from b in db.RoomJoins.Where(fp => fp.roomid == a.roomid && fp.userid != a.userid)
                                 from m in db.Users.Where(m => b.userid == m.id)
                                 join p in db.Chats on a.roomid equals p.roomid into j1
                                 from j2 in j1.DefaultIfEmpty()
                                 group j2 by new { a.roomid, b.userid, m.firstpicurl } into g
                                 select new
                                 {
                                     roomid = g.Key.roomid,
                                     userid = g.Key.userid,
                                     firstpicurl = g.Key.firstpicurl,
                                     count = g.Count()
                                 };

所以我的代码似乎有用,但它有两个问题: 1)它没有考虑时间戳,我只想在我的上一次之后计算一些消息 2)当它应该为0时,我得到1的计数。所以我会得到类似的东西

roomid  userid  firstpicurl  cuenta
1        43     http://...     3
2        37     http://...     1  <-- this should be 0

任何人都知道如何实现我所寻找的目标?

第一个回答: 这个似乎工作,但它看起来非常复杂。有没有办法简化?

from a in db.RoomJoins.Where(c => c.userid == 45 && c.active == true)
                                 from b in db.RoomJoins.Where(fp => fp.roomid == a.roomid && fp.userid != a.userid)
                                 from m in db.Users.Where(m => b.userid == m.id)
                                 from p in db.Chats.Where(p => p.roomid==a.roomid && 
                                            p.sentwhen > a.lastseen).DefaultIfEmpty()
                                 select new
                                 {
                                     roomid = a.roomid,
                                     userid = b.userid,
                                     firstpicurl = m.firstpicurl,
                                     cid = p.Id                                    
                                 } into j1
                                 group j1 by new { j1.roomid, j1.userid, j1.firstpicurl } into g
                                 select new
                                 {
                                     roomid = g.Key.roomid,
                                     userid = g.Key.userid,
                                     firstpicurl = g.Key.firstpicurl,
                                     count = g.Count(e => e.cid!=null)
                                 };

1 个答案:

答案 0 :(得分:0)

import java.sql.Connection;
import java.sql.DriverManager;

public class database {
  public static void main(String[] args) {

    try {
       Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");
       System.out.println("Connection successful");
    } catch (Exception e) {
       System.err.println(e);
    }
  }
}