简体   繁体   English

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

[英]Converting Int to String inside a LINQ expression

I'm creating a SelectList to populate a dropdown list from a LINQ query. 我正在创建一个SelectList来填充LINQ查询中的下拉列表。 This works: 这有效:

// 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");

However, I want the selectItem text to be in the format "group_name (members)", but I can't seem to do that. 但是,我希望selectItem文本采用“group_name(members)”格式,但我似乎无法做到这一点。 if I try 如果我试试

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

I get "Unable to cast the type 'System.Int32' to type 'System.Object'. " If I try 我得到“无法将类型'System.Int32'强制转换为'System.Object'。”如果我尝试

             group_name = g.group_name + mCount.ToString()

I get "LINQ to Entities does not recognize the method 'System.String ToString()' method". 我得到“LINQ to Entities无法识别方法'System.String ToString()'方法”。 If I try 如果我试试

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

I get "LINQ to Entities does not recognize the method 'System.String Format(System.String, System.Object, System.Object)' method". 我得到“LINQ to Entities无法识别方法'System.String Format(System.String,System.Object,System.Object)'方法”。

It just won't let me convert that Int32 into a string. 它只是不允许我将Int32转换为字符串。 It seems like the only option is to create a foreach method that iterates through the GroupWithCount objects and creates a collection of SelectListItems, but that's madness. 似乎唯一的选择是创建一个foreach方法,迭代GroupWithCount对象并创建一个SelectListItems的集合,但这很疯狂。 There must be a better way! 肯定有更好的办法!

If framework is not allowing you to make the change in LINQ query, you can then achieve it once you have received the resultset. 如果框架不允许您在LINQ查询中进行更改,则可以在收到结果集后实现它。 In the resultset, you are already having "mCount" value, you can iterate over the collection and modify the value of group_name accordingly. 在结果集中,您已经具有“mCount”值,您可以迭代集合并相应地修改group_name的值。 For eg 例如

var groups = // your query;

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

When you work with Linq To Entities, you often need to be aware of the boundary between what gets executed on the (database) server, and what gets executed on the client. 当您使用Linq To Entities时,您通常需要了解在(数据库)服务器上执行的内容与在客户端上执行的内容之间的界限。 A useful starting point (though by no means the entire story!) to working this out is observing when you are working with IQueryable (server) and when you are working with IEnumerable (client). 解决这个问题的一个有用的起点 (尽管不是整个故事!)是在使用IQueryable (服务器)和使用IEnumerable (客户端)时观察的。

If you look at the statment you have, that works, and cursor over the var that declares groups , you will see that the compiler has inferred the type IQueryable<GroupWithCount> . 如果你看一下你所拥有的语句,那就可以工作,并将光标放在声明groupsvar上,你会看到编译器已经推断出类型IQueryable<GroupWithCount> That means that when you iterate groups , code will execute on the server . 这意味着当您迭代groups ,代码将在服务器上执行。 In order for this to work, everything in the code needs to be translatable by Entity Framework into SQL. 为了实现这一点,代码中的所有内容都需要由Entity Framework转换为SQL。

Entity Framework is good but not perfect, and one of the things it doesn't know how to do is translate a call to Int32.ToString() into SQL. 实体框架很好但不完美,其中一个不知道如何做的事情就是Int32.ToString()的调用转换为SQL。 So the whole thing gets rejected. 所以整件事都被拒绝了。

In this case , the fix is easy. 在这种情况下 ,修复很容易。 All the information we need is in each GroupWithCount , so we can simply add an .AsEnumerable() , to force server-side evaluation of the query, and then project into the form we want: 我们需要的所有信息都在每个GroupWithCount ,所以我们可以简单地添加一个.AsEnumerable()来强制查询服务器端的评估,然后投影到我们想要的形式:

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()
         };

Everything after the AsEnumerable will be evaluated on the client, so can include arbitrary C# code, including the required ToString call. AsEnumerable之后的所有内容都将在客户端上进行评估,因此可以包含任意C#代码,包括所需的ToString调用。 Examining the var will now show the compiler has inferred a type of IEnumerable<GroupWithCount> . 检查var现在将显示编译器推断出一种IEnumerable<GroupWithCount>

Often it will be the case that we want to do, say, complex filtering on the server, so it wouldn't be a good idea to bring everything back with AsEnumerable - but here it's fine. 通常情况下我们想要在服务器上进行复杂的过滤 ,所以用AsEnumerable带回所有东西并不是一个好主意 - 但这里没关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM