C# 无法使用datatable c上的查询表达式获取所需数据#

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

我想创建一个出现在一个数据表“StatsTable”中的用户排序列表

我需要从StatsTable中获取userID,然后使用它在另一个datatable“UserTable”中查找用户名。当我有了这些,我想让userID成为键,让UserName成为排序列表中的值

我设法获取了userID并将其添加到排序列表中,但用户名是“System.Data.EnumerablerRowCollection`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;
    }
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);