C# 无法使用datatable c上的查询表达式获取所需数据#
我想创建一个出现在一个数据表“StatsTable”中的用户排序列表 我需要从StatsTable中获取userID,然后使用它在另一个datatable“UserTable”中查找用户名。当我有了这些,我想让userID成为键,让UserName成为排序列表中的值 我设法获取了userID并将其添加到排序列表中,但用户名是“System.Data.EnumerablerRowCollection`1[System.String]” 我做错了什么?谢谢你的帮助C# 无法使用datatable c上的查询表达式获取所需数据#,c#,linq,datatable,C#,Linq,Datatable,我想创建一个出现在一个数据表“StatsTable”中的用户排序列表 我需要从StatsTable中获取userID,然后使用它在另一个datatable“UserTable”中查找用户名。当我有了这些,我想让userID成为键,让UserName成为排序列表中的值 我设法获取了userID并将其添加到排序列表中,但用户名是“System.Data.EnumerablerRowCollection`1[System.String]” 我做错了什么?谢谢你的帮助 SortedList Us
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;
}
SortedList用户列表=新建SortedList();
List ListofUserId=StatsTable.AsEnumerable()
.Select(uid=>uid.Field(“UserID”)).ToList();
foreach(ListofUserId中的双UID)
{
字符串userName=UserTable.AsEnumerable()
其中(id=>double.Equals(id.Field(“UserID”),UID))
.Select(name=>name.Field(“First_name”)+“”+name.Field(“Last_name”)).ToString();
UserList[UID]=用户名;
}
代码应如下所示:
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;
}
SortedList用户列表=新建SortedList();
List ListofUserId=StatsTable.AsEnumerable()
.Select(uid=>uid.Field(“UserID”)).ToList();
foreach(ListofUserId中的双UID)
{
字符串userName=UserTable.AsEnumerable()
其中(id=>double.Equals(id.Field(“UserID”),UID))
.Select(name=>name.Field(“First_name”)+“”+name.Field(“Last_name”)).FirstOrDefault().ToString();
UserList[UID]=用户名;
}
您应该在
ToString()
之前添加FirstOrDefault()
,因为,select将为您提供一个新的可枚举对象,而不是一个对象 首先,我会避免对任何需要相等的内容使用double
。字符串、guid和整数对于IDs-double都很好,但不是很多
其次,我将把所有这些都作为LINQ中的一个连接来做——你真的不需要每次迭代每一项。您正在将O(N+M)操作转换为O(N+M*N)操作
第三,您的查询不起作用的原因是您只是在投影到一个字符串序列。你可能碰巧知道只有一场比赛,但你需要告诉电脑。对序列调用ToString()
,不会给您带来任何有用的结果。例如,您可以使用Single()
或SingleOrDefault()
:
string userName=UserTable.AsEnumerable()
其中(id=>double.Equals(id.Field(“UserID”),UID))
.Select(name=>name.Field(“First_name”)+“”
+name.Field(“姓氏”))
.Single();
使用Single()
(或任何其他返回单个值的调用)后,您根本不需要ToString()
,因为结果已经是一个字符串
使用
Single()。使用SingleOrDefault()
,如果有多个结果,仍然会抛出异常,但如果没有结果,则只会得到一个null
引用。如果存在除单个结果以外的任何结果都是错误的,则应使用single()
这是因为您使用的是.AsEnumerable()
,它返回的类型源通常返回一个列表。您可以使用.ToList(
)将其作为列表返回,然后选择第一条记录,也可以使用FirstOrDefault()
;而不是.ToList()
返回第一条记录。您应该使用可枚举。Join
链接两个表并选择所需内容。在本例中,我将使用元组
,而int
是用户ID(带小数点的用户ID没有意义,是吗?),字符串是用户名:
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();
为什么要使用双精度作为ID?总的来说,这是一个非常糟糕的主意。不是我的主意,我使用的是一个已经存在的数据库。除此之外,这并不能回答问题。不,这就是为什么它是一个评论而不是一个答案。你会在页面的其他地方看到我更完整的回答。但是你应该尽快采取行动来解决这个问题。它迟早会咬你的。谢谢,我很感激你的帮助。我确实明白这一点,但我现在对此无能为力,我只能利用我所拥有的。对FirstOrDefault()
的结果调用ToString()
是个坏主意。结果将已经是一个字符串引用-但是如果FirstOrDefault()
返回null,您将得到一个NullReferenceException
。这是一个非常初步的解决方案,他应该处理它,但谢谢Jon!非常感谢您的帮助,非常感谢。:-)蒂姆,你能给我解释一下元组是什么吗?它很好用,但我以前从未听说过。它是用来做什么的?@DavidMuller:你可以把a理解为一个简单的“动态类”。它支持具体化事物,而无需创建具有这些属性的真实类。但是它也有属性Item1
,Item2
,ItemX
等等,这些属性都没有真正的意义。因此,您应该只使用它们的一些属性。
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();
foreach(var user in users)
Console.WriteLine("UserID:{0} UserName:{1}",user.Item1,user.Item2);