web-dev-qa-db-ja.com

C#のLINQの複数列でグループ化

次のようなクラスがあります:

public class ActualClass
{
    public string BookName { get; set; }
    public string IssuerName { get; set; }
    public DateTime DateOfIssue { get; set; }
    public bool Status { get; set; }
}

テーブルには次のデータがあります。 enter image description here

次のviewModelクラスについて、IssuerNameおよびDateOfIssueでそれらをグループ化します。

public class ViewModel
{
   public string IssuerName { get; set; }
   public DateTime DateOfIssue { get; set; }
   public List<string> Books { get; set; }
}

そして、データは次のように表示されます:(スクリーンショットデータは、グループ化が成功した後、前のテーブルデータに置き換えられますenter image description here

特別な注意:私の期待通り、ViewModelに何か問題がありますか?

私はいくつかのstackoverflowの答えに従って多くのことを試しましたが、どれも私のために機能しませんでした。どんな助けも大歓迎です。

私が試したコード:

var viewmodel = from b in db.BookIssues
                group b by new
                {
                    b.IssuerName,
                    b.DateOfIssue
                }
                into g
                select new ViewModel()
                {
                    Name = g.key.IssuerName,
                    DateOfIssue = g.Key.DateOfIssue,
                    Books = g.ToList() //Actually this line of code is not working
                };
11
TanvirArjel

Books = g.ToList()//実際にこの行は機能していません

おそらくBooksプロパティは_List<string>_ではなく_List<ActualClass>_のタイプであるためです。

このクエリを試してみてください、本の名前だけを抽出するb.Select(bn => bn.BookName).ToList()を追加しました:

_var books = new List<ActualClass>
{
   new ActualClass { BookName = "A", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" },
   new ActualClass { BookName = "B", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" },
   new ActualClass { BookName = "C", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" },
   new ActualClass { BookName = "D", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "2" },
   new ActualClass { BookName = "E", DateOfIssue = new DateTime(2015, 10, 10, 12, 10, 0), IssuerName = "2" },
   new ActualClass { BookName = "F", DateOfIssue = new DateTime(2015, 10, 10, 12, 10, 0), IssuerName = "2" }
};

var result = books.GroupBy(x => new { x.IssuerName, x.DateOfIssue })
                .Select(b => new ViewModel
                {
                    Books = b.Select(bn => bn.BookName).ToList(),
                    // Accessing to DateOfIssue and IssuerName from Key.
                    DateOfIssue = b.Key.DateOfIssue,
                    IssuerName = b.Key.IssuerName
                });
_

グループ化:_x.IssuerName, x.DateOfIssue_。 GroupBy()に匿名型を次の方法で渡して、それを行いました:_x => new { x.IssuerName, x.DateOfIssue }_。

これでキーになり、次のようなSELECTステートメントのKEYからIssuerNameおよびDateOfIssueにアクセスできます:_b.Key.IssuerName_および_b.Key.DateOfIssue_。

13
kat1330

グループ結果から書籍のリストを選択する必要がある場合は、Books = v.Select(c=>c.BookName).ToList()が必要です。また、発行日時に時間がある場合は、EntityFunctions.TruncateTime 関数。日付のみを保存する場合は、この関数を無視できます。

var viewmodel  = db.BookIssues.GroupBy(x=>new {IssuerName =x.IssuerName, DateOfIssue=EntityFunctions.TruncateTime(x.DateOfIssue) })
.Select(v=>new ViewModel(){IssuerName =v.Key.IssuerName, DateOfIssue = v.Key.DateOfIssue, Books  = v.Select(c=>c.BookName).ToList() })
.ToList();
3
Damith