简体   繁体   中英

LINQ Lambda for create a list with info from 3 related tables

I am trying to create a ViewModel list with info from Receipt table and then if related info exist in Reason table retreive the last Description inserted (ReceiptId related) and add it (if not just pass null) to the ViewModel Receipt list (RejectDescription). Here's the DB model:

Database Model

I tryied many ways to achieve this, at the moment this is the code that partially works for me, i say partially because in RejectDescription saves the Reason.Description if it exist else just pass null and it's ok.

The main problem is when there's many Reason.Descriptions it doesn't return and save the last one inserted (the most recent, is the one that i am looking for). Here is my code:

    [HttpPost]
    public ActionResult ReceiptList(string Keyword)
    {
        using (SEPRETEntities DBC = new SEPRETEntities())
        {
            long UserId = (long)Session["Id"];
            IEnumerable<Receipt> receipts = DBC.Receipts.Where(x => x.PersonId == UserId && x.Active == true).ToList();

            #region Search
            if (!string.IsNullOrEmpty(Keyword))
            {
                Keyword = Keyword.ToLower();

                receipts = receipts.Where(x => x.Person.Name.ToLower().Contains(Keyword) ||
                x.Person.MiddleName.ToLower().Contains(Keyword) ||
                x.Person.LastName.ToLower().Contains(Keyword) ||
                x.Person.Email.ToLower().Contains(Keyword) ||
                x.Person.Enrollment.ToLower().Contains(Keyword) ||
                x.Person.Career.ToLower().Contains(Keyword) ||
                x.Payment.Name.ToLower().Contains(Keyword) ||
                x.Payment.Price.ToString().ToLower().Contains(Keyword) ||
                x.Method.Name.ToLower().Contains(Keyword) ||
                x.Phase.Name.ToLower().Contains(Keyword) ||
                x.TimeCreated.ToString().ToLower().Contains(Keyword) ||
                x.Voucher.ToString().ToLower().Contains(Keyword)
                );
            }
            #endregion

            List<ReceiptVM> ReceiptList = receipts.Select(x => new ReceiptVM
            {
                Id = x.Id,
                PaymentId = x.PaymentId,
                Enrollment = x.Person.Enrollment,
                Career = x.Person.Career,
                PersonName = string.Concat(x.Person.Name, " ", x.Person.MiddleName, " ", x.Person.LastName),
                Email = x.Person.Email,
                PaymentName = x.Payment.Name,
                MethodName = x.Method.Name,
                Voucher = x.Voucher,
                Image = x.Image,
                PhaseId = x.Phase.Id,
                PriceFormatted = x.Payment.Price.ToString("C"),
                Active = x.Active,
                TimeCreatedFormatted = x.TimeCreated.ToString(),
                RejectDescription = x.Rejections.FirstOrDefault(y => y.ReasonId == y.Reason.Id)?.Reason.Description
            }).ToList();

            return PartialView("~/Views/Receipt/_SearchReceipt.cshtml", ReceiptList);
        }
    }

For you information i am kinda newbie working on C# and ASP.NET MVC.Not sure if there's a better way to achieve this or something, any advice or tip is pretty appreciated.

Thank you and sorry for my bad english

You have to order reject reasons by Id which will fetch recent reason like below:

RejectDescription = x.Rejections.OrderByDescending(x=>x.Reason.Id).FirstOrDefault(y => y.ReasonId == y.Reason.Id)?.Reason.Description

Or you can use LastOrDefault to get most recent one like below: RejectDescription = x.Rejections.LastOrDefault(y => y.ReasonId == y.Reason.Id)?.Reason.Description

 List<ReceiptVM> ReceiptList = receipts.Select(x => new ReceiptVM
                {
                    Id = x.Id,
                    PaymentId = x.PaymentId,
                    Enrollment = x.Person.Enrollment,
                    Career = x.Person.Career,
                    PersonName = string.Concat(x.Person.Name, " ", x.Person.MiddleName, " ", x.Person.LastName),
                    Email = x.Person.Email,
                    PaymentName = x.Payment.Name,
                    MethodName = x.Method.Name,
                    Voucher = x.Voucher,
                    Image = x.Image,
                    PhaseId = x.Phase.Id,
                    PriceFormatted = x.Payment.Price.ToString("C"),
                    Active = x.Active,
                    TimeCreatedFormatted = x.TimeCreated.ToString(),
                    RejectDescription = x.Rejections.OrderByDescending(x=>x.Reason.Id).FirstOrDefault(y => y.ReasonId == y.Reason.Id)?.Reason.Description
                }).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM