2

1つのデータテーブル「StatsTable」に表示されるユーザーの並べ替えられたリストを作成したいと思います。

StatsTableからuserIDを取得し、これを使用して別のデータテーブル「UserTable」でUserNameを見つける必要があります。これらがある場合、userIDをキーにし、UserNameをソート済みリストの値にします。

なんとか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;
    }
4

4 に答える 4

4

まず、double平等を必要とするものには使用しないようにします。文字列、GUID、および整数は、ID にはすべて問題ありません。

次に、これらすべてを LINQ の結合として実行します。毎回すべてのアイテムを反復処理する必要はありません。O(N+M) 操作を O(N + M * N) 操作に変えています。

第三に、クエリが機能しない理由は、単に一連の文字列に投影しているためです。ちょうど 1 つの一致があることをたまたま知っているかもしれませんが、それをコンピュータに伝える必要があります。シーケンスを呼び出し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()と、結果が 1 つだけでない場合に例外がスローされます。を使用するSingleOrDefault()と、複数の結果がある場合でも例外がスローされますがnull、結果がない場合は参照を取得するだけです。単一の結果以外があるとエラーになる場合は、 を使用する必要がありますSingle()

于 2012-12-19T11:09:11.197 に答える
4

を使用Enumerable.Joinして両方のテーブルをリンクし、必要なものを選択する必要があります。この場合、私はユーザーID(小数点以下のユーザーIDは意味がありませんよね?)であり、文字列はユーザ​​ー名ですTuple<int, string>int

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);
于 2012-12-19T11:14:33.087 に答える
2

これは、.AsEnumerable()通常リストを返すタイプのソースを返す を使用しているためです。) を使用してこれをリストとして返し.ToList<string>(、最初のレコードを選択するか、FirstOrDefault();を使用できます。.ToList<string>()最初のレコードを返す代わりに。

于 2012-12-19T11:09:13.973 に答える
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;
}

selectは、単一のオブジェクトではなく、新しい列挙可能なオブジェクトを提供するため、FirstOrDefault()前に追加する必要があります。ToString()

于 2012-12-19T11:07:53.413 に答える