我正在创建一个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的集合,但这很疯狂。肯定有更好的办法!
答案 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
将所有内容带回来是不太好的 - 但这里很好。