在LINQ表达式中将Int转换为String

时间:2011-11-17 14:46:28

标签: c# linq linq-to-entities

我正在创建一个SelectList来填充LINQ查询中的下拉列表。这有效:

// my temp class for including the member count
public class GroupWithCount
{
    public string group_name { get; set; }
    public int group_id { get; set; }
    public int members { get; set; }        
}

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
         };
 model.Groups = new SelectList(groups, "group_id", "group_name");

但是,我希望selectItem文本的格式为“group_name(members)”,但我似乎无法做到这一点。如果我试试

         select new GroupWithCount
         {
             members = mCount,
             group_id = g.group_id,
             group_name = g.group_name + mCount 
         };

我得到“无法将类型'System.Int32'强制转换为'System.Object'。”如果我尝试

             group_name = g.group_name + mCount.ToString()

我得到“LINQ to Entities无法识别方法'System.String ToString()'方法”。如果我试试

             group_name = string.Format("{0}{1}", g.group_name,mCount)

我得到“LINQ to Entities无法识别方法'System.String Format(System.String,System.Object,System.Object)'方法”。

它只是不允许我将Int32转换为字符串。似乎唯一的选择是创建一个foreach方法,迭代GroupWithCount对象并创建一个SelectListItems的集合,但这很疯狂。肯定有更好的办法!

2 个答案:

答案 0 :(得分:3)

如果框架不允许您在LINQ查询中进行更改,则可以在收到结果集后实现它。在结果集中,您已经具有“mCount”值,您可以迭代集合并相应地修改group_name的值。对于例如

var groups = // your query;

groups.ForEach(item => item.group_name = item.group_name + item.mCount.ToString);

答案 1 :(得分:2)

当您使用Linq To Entities时,您通常需要了解在(数据库)服务器上执行的内容与在客户端上执行的内容之间的界限。一个有用的起点(虽然绝不是整个故事!)来解决这个问题,观察你在使用IQueryable(服务器)和使用{{1}时的时间(客户)。

如果你看一下你所拥有的那个,那就可以了,并将光标放在声明IEnumerable的{​​{1}}上,你就会看到编译器推断出类型var。这意味着当您迭代groups时,代码将在服务器上执行。为了实现这一点,代码中的所有内容都需要由Entity Framework转换为SQL。

实体框架很好但不完美,其中一个不知道如何做的事情是将对IQueryable<GroupWithCount>的调用转换为SQL。所以整件事都被拒绝了。

在这种情况下,修复很简单。我们需要的所有信息都在groups中,因此我们只需添加Int32.ToString(),强制对查询进行服务器端评估,然后投影到我们想要的格式:

GroupWithCount

.AsEnumerable()之后的所有内容都将在客户端上进行评估,因此可以包含任意C#代码,包括所需的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() // come to the client // next Select is evaluated on the client .Select(gwc => new GroupWithCount { members = gwc.members, group_id = gwc.group_id, group_name = gwc.group_name + gwc.members.ToString() }; 调用。现在,检查AsEnumerable将显示编译器已推断出ToString的类型。

通常情况下我们想在服务器上执行复杂的过滤,因此用var将所有内容带回来是不太好的 - 但这里很好。