我想创建一个显示在一个数据表“StatsTable”中的用户的排序列表。
我需要从StatsTable获取userID,然后使用它来在另一个数据表“UserTable”中查找UserName。当我有这些时,我想让userID成为Key,UserName成为排序列表中的Value。
我设法获取userID并将其添加到排序列表中,但userName以“System.Data.EnumerableRowCollection`1 [System.String]”的形式出现。
我做错了什么?谢谢你的帮助。
SortedList UserList = new SortedList();
List<double> listofUserIDs = StatsTable.AsEnumerable()
.Select(uid => uid.Field<double>("UserID")).ToList<double>();
foreach (double UID in listofUserIDs)
{
string userName = UserTable.AsEnumerable()
.Where(id => double.Equals(id.Field<double>("UserID"), UID))
.Select(name => name.Field<string>("First_Name") + " " + name.Field<string>("Last_Name")).ToString();
UserList[UID] = userName;
}
答案 0 :(得分:4)
首先,我会避免将double
用于任何需要平等的事情。字符串,GUID和整数都适用于ID - 双倍,而不是。
其次,我将所有这些作为LINQ中的联接 - 您实际上不需要每次都迭代每个项目。您正在将O(N + M)操作转换为O(N + M * N)操作。
第三,您的查询无效的原因是您只是投射到字符串的序列。您可能碰巧知道将只有一个匹配,但您需要告诉计算机。在序列上调用ToString()
不会给你任何有用的东西。例如,您可以使用Single()
或SingleOrDefault()
:
string userName = UserTable.AsEnumerable()
.Where(id => double.Equals(id.Field<double>("UserID"), UID))
.Select(name => name.Field<string>("First_Name") + " "
+ name.Field<string>("Last_Name"))
.Single();
一旦您使用Single()
(或任何其他返回单个值的调用),您根本不需要ToString()
,因为结果将是一个字符串。
使用Single()
时,如果没有一个结果,则会抛出异常。使用SingleOrDefault()
时,如果有多个结果,仍会抛出异常,但如果没有结果,您只会获得null
引用。如果除了单个结果之外还有其他任何内容都是错误的,那么您应该使用Single()
。
答案 1 :(得分:4)
您应该使用Enumerable.Join
链接两个表并选择所需内容。在这种情况下,我会使用Tuple<int, string>
,而int
是UserID(带有小数位的UserID没有意义,是吗?),字符串是用户名:
var query = from rStats in StatsTable.AsEnumerable()
join rUser in UserTable.AsEnumerable()
on rStats.Field<int>("UserID") equals rUser.Field<int>("UserID")
select new {
UserID = rStats.Field<int>("UserID"),
UserName = string.Format("{0} {1}"
, rUser.Field<string>("First_Name")
, rUser.Field<string>("Last_Name"))
};
List<Tuple<int, string>> users = query
.OrderBy(u => u.UserName)
.Select(u => Tuple.Create(u.UserID, u.UserName))
.ToList();
您可以通过Item
属性访问元组:
foreach(var user in users)
Console.WriteLine("UserID:{0} UserName:{1}",user.Item1,user.Item2);
答案 2 :(得分:2)
这是因为您正在使用.AsEnumerable()
返回通常返回列表的类型的源。您可以使用.ToList<string>(
)将其作为列表返回并选择第一条记录,也可以使用FirstOrDefault()
;而不是.ToList<string>()
来返回第一条记录。
答案 3 :(得分:1)
代码应如下所示:
SortedList UserList = new SortedList();
List<double> listofUserIDs = StatsTable.AsEnumerable()
.Select(uid => uid.Field<double>("UserID")).ToList<double>();
foreach (double UID in listofUserIDs)
{
string userName = UserTable.AsEnumerable()
.Where(id => double.Equals(id.Field<double>("UserID"), UID))
.Select(name => name.Field<string>("First_Name") + " " + name.Field<string>("Last_Name")).FirstOrDefault().ToString();
UserList[UID] = userName;
}
您应该在FirstOrDefault()
之前添加ToString()
,因为,select会为您提供一个新的可枚举,而不是一个对象!