2

モデル内のリストを取得するにはどうすればよいですか?

これは私がしようとしているものです:

private void cbxPlayers_SelectedValueChanged(object sender, EventArgs e)
        {
            List<Record> records = new List<Record>();
            string selectedPlayer = cbxPlayers.SelectedItem.ToString();
            using (ProgressRecordContext context = new ProgressRecordContext())
            {
                records = (from Player in context.Players
                          where Player.Name == selectedPlayer
                          select Player.Records).ToList<Record>();
            }
        }

それは機能しませんが、何が欠けていますか?

必要な場合のモデルは次のとおりです。

public class Player
    {
        [Key][DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int AccountNumberId { get; set; }

        public string Name { get; set; }

        public virtual List<Record> Records { get; set; }
    }

public class Record
    {
        public int RecordId { get; set; }
        public int AccountNumberId { get; set; }

        public double Level { get; set; }
        public int Economy { get; set; }
        public int Fleet { get; set; }
        public int Technology { get; set; }
        public int Experience { get; set; }

        public DateTime TimeStamp { get; set; }

        public virtual Player Player { get; set; }
    }

編集:エラーメッセージは次のとおりです。

エラー 1 'System.Linq.IQueryable>' には 'ToList' の定義が含まれておらず、最適な拡張メソッド オーバーロード 'System.Linq.ParallelEnumerable.ToList(System.Linq.ParallelQuery)' に無効な引数がいくつか含まれています

エラー 2 インスタンス引数: 'System.Linq.IQueryable>' から 'System.Linq.ParallelQuery' に変換できません

編集:

自分が何をしようとしていたのか、おそらくあまり明確ではなかったことがわかります。私は最終的に、私が望んでいたことを行う方法を考え出しました。

private void cbxPlayers_SelectedValueChanged(object sender, EventArgs e)
        {
            lstvRecords.Items.Clear();
            if(cbxPlayers.SelectedIndex == -1)
            {
                return;
            }
            string selectedPlayer = cbxPlayers.SelectedItem.ToString();
            using (ProgressRecordContext context = new ProgressRecordContext())
            {
                var records = from Player in context.Players
                          from Record in context.Records
                          where Player.Name == selectedPlayer &&
                          Player.AccountNumberId == Record.AccountNumberId
                          select new
                          {
                              Level = Record.Level,
                              Economy = Record.Economy,
                              Fleet = Record.Fleet,
                              Technology = Record.Technology,
                              Experience = Record.Experience,
                              TimeStamp = Record.TimeStamp
                          };

                foreach (var element in records)
                {
                    string[] elements = {element.Level.ToString(),
                                            element.Economy.ToString(),
                                            element.Fleet.ToString(),
                                            element.Technology.ToString(),
                                            element.Experience.ToString(),
                                            element.TimeStamp.ToString()
                                        };
                    ListViewItem lvi = new ListViewItem(elements);
                    lstvRecords.Items.Add(lvi);
                }
            }
        }

そのクエリを記述するより良い方法はありますか、それとも私が行った方法は正しいですか?

4

4 に答える 4

6

ソースファイルにParallelQuery奇抜な s が含まれていない限り、なぜ取得しているのかわかりません。using

いずれにせよ、列挙型の列挙型があるようです-試してください(これが拡張メソッドとしても機能するSelectMany必要があることに注意してください):using System.Linq;

records = (from Player in context.Players 
           where Player.Name == selectedPlayer 
           select Player.Records).SelectMany(r => r).ToList();

また、そのリストに追加/リストから削除するつもりがない限り、配列を使用する必要があります.ToArray()

@Tim S (+1) で指摘されているように、ここで単一のプレーヤーのみを期待する場合は、単一のプレーヤーSingleOrDefault()を取得するために使用する必要がありRecordsます。これを配列/リストに変換します。

于 2012-10-08T12:43:10.290 に答える
2

あなたの問題は でPlayer.RecordsありList<Record>IEnumerable<List<Record>>クエリから (つまり、0 から多くのプレーヤーのレコード) を取得しているため、 を.ToList()取得しますList<List<Record>>。同じ名前のプレイヤーが複数いて、それらすべてからレコードを収集したい場合は、Andras Zoltan のソリューションを使用してください。(結果が 0 個または 1 個以上の場合に例外をスローすることにより) 確実に 1 人のプレーヤーが指定された名前を持ち、そのプレーヤーのレコードのみが返されるようにする場合は、次のいずれかのソリューションを使用します.Single()SingleOrDefaultそれがあなたのニーズにより適しているかどうかを確認するために見てください)

//I prefer this solution for its conciseness and clarity.
records = context.Players.Single(Player => Player.Name == selectedPlayer).Records;

//if you'd like to use the LINQ query format, I'd recommend this.
records = (from Player in context.Players
          where Player.Name == selectedPlayer
          select Player).Single().Records;

//this is more similar to your original query.
records = (from Player in context.Players
          where Player.Name == selectedPlayer
          select Player.Records).Single().ToList();
于 2012-10-08T13:18:57.453 に答える
0

クエリのリファクタリングを試すことができます

records = context.Players.First(player => player.Name == selectedPlayer).Records.ToList();
于 2012-10-08T14:37:35.677 に答える
0

変えたら

     List<Record> records = new List<Record>();

     var records = new List<List<Record>>();

それは機能しますか?Player にレコードのリストがある場合、クエリはレコードのリストのリストを返しているように見えます。

編集:そこに、戻りリストを修正しました...いずれにせよ、これはおそらくあなたが探している解決策ではなく、問題が何であるかを強調しているだけです。

于 2012-10-08T12:45:05.407 に答える