2015-09-25 5 views
0

У меня есть система чата, состоящая из 3 таблиц: Users, RoomJoins (закрытая беседа, к которой вы присоединились) и чатов (список сообщений чата с меткой времени).Entity Framework несколько типов объединения с датами, группами по и счету

Я хочу получить список всех частных комнат для данного пользователя, а затем число новых сообщений чата, которые он получил с момента последнего входа в систему.

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 

, что в основном говорит: дайте мне все roomids (частные разговоры) для идентификатора пользователя = 45, а также идентификатор пользователя из человек, который прислал мне сообщение, его изображение и количество сообщений чата, где sentwhen> user.lastseen

результат будет что-то вроде

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

означая userid 43 отправил вам 3 сообщения с момента вашего последнего входа, в то время как пользователь 37 не отправил вам ничего нового

Теперь я пытаюсь перевести это в EF, и я вроде как его работаю, но проблема в том, что я не может найти способ запроса с использованием формата datewhen> lastseen date, поскольку он этого не позволяет. И если я попытаюсь с предложениями Where, я никогда не получу правильный ответ. Вот мой существующий попытка (без sentwhen> 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() 
           }; 

мой код, кажется, работает, но есть 2 проблемы: 1) он не принимает во внимание временную метку, я просто хочу, счетчик сообщений после моего lastseen 2) Я получаю количество 1, когда он должен быть равен 0. Таким образом, я хотел бы получить что-то вроде этого

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) 
           }; 
+0

Что происходит, когда вы добавляете дополнительные присоединиться на ограничение на вступление заявление таблицы р? Как вы это делали в своем sql-запросе? –

+0

, независимо от производительности, предложение 'Where' должно всегда работать. Это не работает, это означает, что ваш запрос LINQ неверен в какой-то другой точке. – Hopeless

+0

Общие рекомендации, что я могу дать, не тратьте время на перевод SQL-запросов в EF. Это просто противодействует продуктивности без каких-либо дополнительных преимуществ. Я научился этому трудно в проекте, где я даже не мог контролировать схему базы данных, и каждый запрос занимал в 3 раза больше, чем писать: один раз в sql, который был знаком, второй в EF, а третий выясняет, почему все еще не работает. EF блестящий с простыми схемами, а также очень хорошо подходит для отслеживания изменений. Остальное вызовите SP. –

ответ

0
join p in db.Chats.Where(x => x.sentwhen > a.lastseen) 
       on a.roomid equals p.roomid into j1 
+0

вы не можете сделать соединение/где/на –

+0

@JoaquinGrech Попробовали? –

+0

, очевидно, это было первое, что я сделал, копирование и вставка ... немедленная ошибка, она не понимает, что вы помещаете «on» после метода Where. Вы можете попробовать сами. –