When you work with Linq To Entities, you often need to know the boundary between what is running on the server (database) and what is running on the client. A useful starting point (although by no means the whole story!), To work on this, it is observed when you work with IQueryable (server) and when you work with IEnumerable (client).
If you look at the statute that you have, it works and hover over var declaring groups , you will see that the compiler has IQueryable<GroupWithCount> type IQueryable<GroupWithCount> . This means that when the group iteration is repeated, the code will be executed on the server. For this to work, everything in the code must be translatable by the Entity Framework in SQL.
The Entity Framework is good, but not perfect, and one of the things that it does not know how to do is translate the Int32.ToString() call into SQL. Therefore, all this is rejected.
In this case, fixing is easy. All the information we need is in every GroupWithCount , so we can simply add .AsEnumerable() to force a server-side request evaluation and then project it into the desired form:
var groups = (from g in DB.Groups where g.user_id == user_id let mC=(from c in DB.Contacts where c.group_id == g.group_id select c).Count() select new GroupWithCount { members = mC, group_id = g.group_id, group_name = g.group_name }) .AsEnumerable()
Everything after AsEnumerable will be evaluated on the client, so it can include arbitrary C # code, including the required ToString call. Examining var will now show that the compiler has IEnumerable<GroupWithCount> type IEnumerable<GroupWithCount> .
Often this will be the case that we want to do, say, complex filtering on the server, so it would be nice to return everything with AsEnumerable - but here it is fine.