there is a table of messages. scheme:
CREATE TABLE [dbo].[Messages] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[DateCreate] DATETIME2 (7) DEFAULT (getdate()) NOT NULL,
[SenderId] INT NOT NULL,
[RecipientId] INT NOT NULL,
[TextMessage] NVARCHAR (MAX) NULL,
[IsReaded] BIT NOT NULL,
CONSTRAINT [PK_Messages] PRIMARY KEY CLUSTERED ([Id] ASC)
);
I want to get a table:
- sender_id [int] - sender id key
- all_count_messages [int] - number of messages from the sender
- count_unreaded_messages [int] - number of unread messages from the sender
- most_unreaded [DateTime] - the date of the most old unread messages
I also need group by [sender_id] and sort the output. Good. I make a simple request:
SELECT
message.SenderId AS sender_id,
COUNT(*) AS all_count_messages,
SUM(CAST(
CASE
WHEN IsReaded = 0
THEN 1
ELSE 0
END AS int)) as count_unreaded_messages,
MIN(message.DateCreate) AS most_unreaded
FROM
Messages AS message
GROUP BY
message.SenderId
ORDER BY
most_unreaded
demo result:
sender_id all_count_messages unreaded_messages most_unreaded
2 3 2 2019-08-15 20:03:59.0000000
1 9 8 2019-08-15 20:04:59.0000000
the answer suits me. how to describe it on EFCore?
try it
var chats = from my_messages in db.Messages
group my_messages by my_messages.SenderId into g
select
new
{
sender_id = g.Key,
all_count_messages = g.Count(),
unreaded_messages = from sub_messages in db.Messages where sub_messages.SenderId == g.Key && !sub_messages.IsReaded group sub_messages by sub_messages.SenderId into sub_g select sub_g.Count(),
most_unreaded = from sub_messages in db.Messages where sub_messages.SenderId == g.Key && !sub_messages.IsReaded group sub_messages by sub_messages.SenderId into sub_g select sub_g.Min(x => x.DateCreate)
};
foreach (var chat in chats) // so, too, has tried: chats.Include(x=>x.unreaded_messages).Include(x => x.most_unreaded)
{
}
get error in foreach (var chat in chats)
An unhandled exception occurred while processing the request.
ArgumentException: must be reducible node
System.Linq.Expressions.Expression.ReduceAndCheck()
I tried otherwise:
var chats = db.Messages.AsNoTracking().FromSql(
"SELECT" +
" message.SenderId AS sender_id," +
" COUNT(*) AS all_count_messages," +
" SUM(CAST(" +
" CASE" +
" WHEN IsReaded = 0" +
" THEN 1" +
" ELSE 0" +
" END AS int)) as count_unreaded_messages," +
" MIN(message.DateCreate) AS most_unreaded " +
"FROM " +
" Messages AS message " +
"GROUP BY " +
" message.SenderId " +
"ORDER BY" +
" most_unreaded ");
foreach (var chat in chats)
{
}
get error in foreach (var chat in chats)
InvalidOperationException: The required column 'Id' was not present in the results of a 'FromSql' operation.
Microsoft.EntityFrameworkCore.Query.Sql.Internal.FromSqlNonComposedQuerySqlGenerator.CreateValueBufferFactory(IRelationalValueBufferFactoryFactory relationalValueBufferFactoryFactory, DbDataReader dataReader)