2 Soalan: Linq Group Dengan Fasal tidak termasuk item dengan kiraan sifar

soalan dicipta di Wed, May 8, 2019 12:00 AM

Saya mempunyai pertanyaan di bawah yang sepatutnya mengelompokkan hasilnya oleh Id, EntityName, DocType, Bidang kuasa. Bagi setiap kumpulan, pertanyaan juga mengembalikan item ProductList.

Pada masa ini jika kumpulan itu mengandungi satu atau lebih daripada satu produk, Kemudian saya dapat melihat hasil yang memberikan sebuah kumpulan dengan gabungan Id, EntityName, DocType, Bidang Kuasa dan ProductList, Tetapi jika hasilnya tidak mengandungi produk untuk kumpulan tertentu saya tidak melihat kumpulan sama sekali. Apa yang saya ingin lakukan adalah menunjukkan kumpulan walaupun tidak mempunyai sebarang produk dalam kumpulannya. Jadi jika kiraan ProductList adalah sifar, saya ingin menetapkan       ProductList = Senarai baru NettingAgreementProductDto. Sebarang input akan sangat dihargai.

          var result = from nae in nettingAgreementEntities.Result
                     join no in nettingOpinions.Result 
                          on nae.EntityId equals no.EntityId 
                     join np in nettingProducts.Result 
                          on no.ProductId equals np.Id
                     group np by new 
                               { nae.EntityId, 
                                 nae.EntityName, 
                                 nae.DocType,
                                 nae.Jurisdiction 
                               } into g                      
                     select new NettingAgreementEntityDto
                     {
                         Id = g.Key.EntityId,
                         EntityName = g.Key.EntityName,
                         DocType = g.Key.DocType,
                         Jurisdiction = g.Key.Jurisdiction,
                         ProductList =  g.Select(x => new                                            
                                        NettingAgreementProductDto
                                        {
                                           Id = x.Id,
                                           Name = x.Name
                                        }).ToList()
                     };
    
2
  1. Bukankah nae.EntityId unik dalam nettingAgreementEntities.Result? Ini terdengar lebih seperti calon untuk Berkelompok Sertai daripada (dalam) Join + GroupBy. Kini Masuk Dalaman menapis pertanyaan anda,
    2019-05-09 08: 24: 19Z
  2. Hi @IvanStoev Adakah anda mengatakan selagi saya mempunyai nae.EntityId di dalam batin saya tidak akan mendapat hasil yang saya mahu?
    2019-05-09 08: 35: 28Z
  3. Tidak. Saya mengatakan bahawa pertanyaan semasa anda mengandungi 2 gabungan batin, yang akan menyaring nae tanpa no dan no tanpa np. Sementara GroupJoin (atau kiri dilampirkan) tidak akan melakukannya.
    2019-05-09 08: 39: 45Z
  4. Hi @IvanStoev saya mengejek pertanyaan berdasarkan cadangan anda. jika saya menghantar pertanyaan saya sebagai jawapan anda akan dapat membetulkannya? ia bertiup apabila saya cuba membuat bahagian luar kiri.
    2019-05-09 09: 34: 51Z
  5. Pasti .. Tetapi saya perlukan kelas entiti /kelas yang terlibat. Dan definisi nettingAgreementEntities.Result, nettingOpinions.Result dan nettingProducts.Result - adalah ini IQueryables dari EF dll.
    2019-05-09 10: 18: 46Z
2 Jawapan                              2                         

Untuk merakam dari komen, pada masa ini pertanyaan anda menggunakan Masuk Dalaman untuk mengaitkan NettingAgreementEntity dengan NettingAgreementProducts. Ini bukan sahaja mengagihkan set keputusan (dan dengan itu memerlukan anda menggunakan GroupBy selepas), tetapi juga menyaring NettingAgreementEntity tanpa NettingAgreementProducts.

Anda boleh mencapai matlamat dengan menukar ke Sertai Kumpulan menyertai "rel =" nofollow noreferrer "> Left Outer Join + GroupBy).

Tetapi mengapa memasuki semua komplikasi ini. Ciri-ciri navigasi EF membolehkan anda hampir melupakan hubungan manual, dan juga membolehkan anda dengan mudah melihat kepelbagaian, oleh itu sama ada anda perlu mengumpulkan hasilnya atau tidak.

Jadi apa yang saya cadangkan ialah menambah harta navigasi pengumpulan yang sedang hilang ke kelas NettingAgreementEntity:

public class NettingAgreementEntity
{
    // ...
    public virtual ICollection<NettingOpinion> Opinions { get; set; }
}

Opsyenal melakukan perkara yang sama untuk NettingAgreementProduct sekiranya pada masa akan datang anda memerlukan sesuatu yang serupa untuk produk (ini banyak hubungan dan harus dapat dipertanyakan dari kedua-dua pihak).

Juga saya akan menamakan semula sifat pelayaran kelas NettingOpinion NettingAgreementProductNavigation dan NettingAgreementEntityNavigation kepada sesuatu yang lebih pendek, contohnya Product dan Entity. Nama-nama ini (serta nama-nama sifat navigasi pengumpulan) tidak mempengaruhi skema pangkalan data, tetapi IMHO menyediakan pembacaan yang lebih baik.

Sekali anda memilikinya, anda akan melihat bahawa pertanyaan LINQ yang dikehendaki adalah perkara mudah Selects yang menukar kelas entiti kepada DTO dan biarkan penterjemah pertanyaan EF menghasilkan gabungan yang diperlukan untuk anda:

var result = db.Set<NettingAgreementEntity>()
    .Selec(nae => new NettingAgreementEntityDto
    {
        Id = nae.EntityId,
        EntityName = nae.EntityName,
        DocType = nae.DocType,
        Jurisdiction = nae.Jurisdiction,
        ProductList = nae.Opinions
            .Select(no => new NettingAgreementProductDto
            {
                no.Product.Id,
                no.Product.Name,
            }).ToList(),
    });
    
2
2019-05-09 12: 51: 29Z
  1. Terima kasih atas bantuan anda. Saya telah mengemas kini jawapan saya (pertanyaan akhir) berdasarkan cadangan anda dan kini ia berfungsi.
    2019-05-09 21: 16: 21Z

Berikut adalah apa yang saya cuba setakat ini. Saya percaya pertanyaan itu tidak cukup tepat pada peringkat ini kerana ia masih menghilangkan kumpulan yang tidak mempunyai produk.

NettingOpinion Entity

[Table("NettingOpinion",Schema = "dbo")]
public class NettingOpinion
{
    [Key]
    [Column("NettingOpinionID")]
    public int NettingOpinionId { get; set; }

    [Column("ProductID")]
    public int ProductId { get; set; }

    [Column("EntityID")]
    public int EntityId { get; set; }

    [ForeignKey("ProductId")]
    public virtual  NettingAgreementProduct NettingAgreementProductNavigation { get; set; }

    [ForeignKey("EntityId")]
    public virtual  NettingAgreementEntity NettingAgreementEntityNavigation { get; set; }
}  

NettingAgreementProduk Produk

    public  class NettingAgreementProduct
    {
        public NettingAgreementProduct()
        {
            NettingAgreementDefaults = new HashSet<NettingAgreementDefaults>();
        }

        [Column("ProductID")]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }

        [Required]
        [Column("ProductName")]
        [StringLength(255)]
        public string Name { get; set; }

        public virtual ICollection<NettingAgreementDefaults> NettingAgreementDefaults { get; set; }
    }

NettingAgreementEntity

[Table("NettingAgreementEntity")]
public class NettingAgreementEntity
{
    [Key]
    [Column("EntityID")]
    public int EntityId { get; set; }

    [MaxLength(50,ErrorMessage = "DocType Cannot be more than 50 characters")]
    [Required]
    public string DocType { get; set; }


    [Column("Jurisdiction")]
    [MaxLength(2, ErrorMessage = "Jurisdiction Cannot have more than two characters")]
    [Required]
    public string Jurisdiction { get; set; }

    [MaxLength(255,ErrorMessage = "EntityName Cannot have more than 255 characters")]
    [Required]
    public string EntityName { get; set; }

    [ForeignKey("DocType")]
    public virtual  DocType DocTypeNavigation { get; set; }

}

Pertanyaan Sebenar

                     var result = from nae in nettingAgreement
                     join no in nettingOpinion on nae.EntityId equals no.EntityId into pp
                     from test in pp.DefaultIfEmpty(new NettingOpinion())
                     join np in nettingProduct on test.ProductId equals np.Id into npd
                     from npdSubset in npd.DefaultIfEmpty()
                     group npdSubset by new { nae.EntityId, nae.EntityName, nae.DocType, nae.Jurisdiction } into g
                     select new NettingAgreementEntityDto
                     {
                         Id = g.Key.EntityId,
                         EntityName = g.Key.EntityName,
                         DocType = g.Key.DocType,
                         Jurisdiction = g.Key.Jurisdiction,
                         ProductList =  g.Select(x => new NettingAgreementProductDto
                         {
                             Id = x?.Id ?? 0,
                             Name = x == null ? string.Empty : x.Name
                         }).ToList()
                     };
    
0
2019-05-09 21: 15: 52Z
  1. Berdasarkan cadangan @Ivan Stoev saya telah mengemas kini jawapan saya (pertanyaan akhir) yang sedang berjalan sekarang.
    2019-05-09 21: 17: 58Z
sumber diletakkan di sini