[c#] LINQ 람다에서 여러 테이블 간 조인을 수행하는 방법

LINQ에서 여러 테이블간에 조인 을 수행하려고합니다 . 다음과 같은 수업이 있습니다.

Product {Id, ProdName, ProdQty}

Category {Id, CatName}

ProductCategory{ProdId, CatId} //association table

그리고 나는 다음과 같은 코드를 사용 (여기서 product, categoryproductcategory위 클래스의 인스턴스) :

var query = product.Join(productcategory, p => p.Id, pc => pc.ProdID, (p, pc) => new {product = p, productcategory = pc})
                   .Join(category, ppc => ppc.productcategory.CatId, c => c.Id, (ppc, c) => new { productproductcategory = ppc, category = c});

이 코드를 사용하여 다음 클래스에서 객체를 얻습니다.

QueryClass { productproductcategory, category}

producproductcategory가 유형 인 경우 :

ProductProductCategoryClass {product, productcategory}

조인 된 “테이블”이 어디에 있는지 이해하지 못합니다 . 관련된 클래스의 모든 속성을 포함 하는 단일 클래스 를 예상했습니다 .

내 목표는 쿼리에서 생성 된 일부 속성으로 다른 개체를 채우는 것입니다.

CategorizedProducts catProducts = query.Select(m => new { m.ProdId = ???, m.CatId = ???, //other assignments });

이 목표를 어떻게 달성 할 수 있습니까?



답변

조인의 경우 행복하게 숨겨지는 모든 세부 사항에 대해 쿼리 구문을 강력히 선호합니다 (그 중 최소한 점 구문에서 명백한 중간 프로젝션과 관련된 투명한 식별자는 아닙니다). 그러나 필요한 모든 것을 갖추고 있다고 생각하는 Lambda에 대해 물었습니다.

var categorizedProducts = product
    .Join(productcategory, p => p.Id, pc => pc.ProdId, (p, pc) => new { p, pc })
    .Join(category, ppc => ppc.pc.CatId, c => c.Id, (ppc, c) => new { ppc, c })
    .Select(m => new {
        ProdId = m.ppc.p.Id, // or m.ppc.pc.ProdId
        CatId = m.c.CatId
        // other assignments
    });

필요한 경우 조인을 지역 변수에 저장하고 나중에 다시 사용할 수 있지만 반대로 다른 세부 정보가 부족하여 지역 변수를 도입 할 이유가 없습니다.

또한 Select두 번째 람다의 마지막 람다에 넣을 수 있습니다 Join(다시 조인 결과에 의존하는 다른 작업이없는 경우).

var categorizedProducts = product
    .Join(productcategory, p => p.Id, pc => pc.ProdId, (p, pc) => new { p, pc })
    .Join(category, ppc => ppc.pc.CatId, c => c.Id, (ppc, c) => new {
        ProdId = ppc.p.Id, // or ppc.pc.ProdId
        CatId = c.CatId
        // other assignments
    });

… 그리고 쿼리 구문에 대해 마지막으로 판매하려고 시도하면 다음과 같습니다.

var categorizedProducts =
    from p in product
    join pc in productcategory on p.Id equals pc.ProdId
    join c in category on pc.CatId equals c.Id
    select new {
        ProdId = p.Id, // or pc.ProdId
        CatId = c.CatId
        // other assignments
    };

쿼리 구문을 사용할 수 있는지 여부에 따라 손이 묶일 수 있습니다. 나는 일부 상점이 그러한 명령을 가지고 있음을 알고 있습니다. 종종 쿼리 구문이 도트 구문보다 다소 제한적이라는 개념에 기반합니다. “내가 도트 구문으로 모든 것을 할 수 있다면 왜 두 번째 구문을 배워야합니까?”와 같은 다른 이유가 있습니다. 이 마지막 부분이 보여 주듯이-가독성 향상과 함께 수용 할 가치가있는 쿼리 구문이 숨기는 세부 사항이 있습니다. 요리해야하는 모든 중간 프로젝션과 식별자는 기꺼이 앞과 가운데가 아닙니다. 쿼리 구문 버전의 단계-백그라운드 보풀입니다. 지금 내 비누 상자에서-어쨌든, 질문 주셔서 감사합니다. 🙂


답변

당신이 본 것은 당신이 얻는 것입니다-정확히 당신이 요청한 것입니다.

(ppc, c) => new { productproductcategory = ppc, category = c}

이 두 속성이있는 익명 형식을 반환하는 람다 식입니다.

CategorizedProducts에서 다음 속성을 통해 이동하면됩니다.

CategorizedProducts catProducts = query.Select(
      m => new {
             ProdId = m.productproductcategory.product.Id,
             CatId = m.category.CatId,
             // other assignments 
           });


답변

내 프로젝트에서이 샘플 코드를보세요

public static IList<Letter> GetDepartmentLettersLinq(int departmentId)
{
    IEnumerable<Letter> allDepartmentLetters =
        from allLetter in LetterService.GetAllLetters()
        join allUser in UserService.GetAllUsers() on allLetter.EmployeeID equals allUser.ID into usersGroup
        from user in usersGroup.DefaultIfEmpty()// here is the tricky part
        join allDepartment in DepartmentService.GetAllDepartments() on user.DepartmentID equals allDepartment.ID
        where allDepartment.ID == departmentId
        select allLetter;

    return allDepartmentLetters.ToArray();
}

이 코드에서 3 개의 테이블을 조인하고 where 절에서 조인 조건을 확인했습니다.

참고 : 서비스 클래스는 데이터베이스 작업을 왜곡 (캡슐화)합니다.


답변

 public ActionResult Index()
    {
        List<CustomerOrder_Result> obj = new List<CustomerOrder_Result>();

       var  orderlist = (from a in db.OrderMasters
                         join b in db.Customers on a.CustomerId equals b.Id
                         join c in db.CustomerAddresses on b.Id equals c.CustomerId
                         where a.Status == "Pending"
                         select new
                         {
                             Customername = b.Customername,
                             Phone = b.Phone,
                             OrderId = a.OrderId,
                             OrderDate = a.OrderDate,
                             NoOfItems = a.NoOfItems,
                             Order_amt = a.Order_amt,
                             dis_amt = a.Dis_amt,
                             net_amt = a.Net_amt,
                             status=a.Status,
                             address = c.address,
                             City = c.City,
                             State = c.State,
                             Pin = c.Pin

                         }) ;
       foreach (var item in orderlist)
       {

           CustomerOrder_Result clr = new CustomerOrder_Result();
           clr.Customername=item.Customername;
           clr.Phone = item.Phone;
           clr.OrderId = item.OrderId;
           clr.OrderDate = item.OrderDate;
           clr.NoOfItems = item.NoOfItems;
           clr.Order_amt = item.Order_amt;
           clr.net_amt = item.net_amt;
           clr.address = item.address;
           clr.City = item.City;
           clr.State = item.State;
           clr.Pin = item.Pin;
           clr.status = item.status;

           obj.Add(clr);



       }


답변

var query = from a in d.tbl_Usuarios
                    from b in d.tblComidaPreferidas
                    from c in d.tblLugarNacimientoes
                    select new
                    {
                        _nombre = a.Nombre,
                        _comida = b.ComidaPreferida,
                        _lNacimiento = c.Ciudad
                    };
        foreach (var i in query)
        {
            Console.WriteLine($"{i._nombre } le gusta {i._comida} y nació en {i._lNacimiento}");
        }


답변

오래되었지만 내 대답은 누군가를 도울 수 있습니다.

이미 관계를 올바르게 정의한 경우 다음을 사용할 수 있습니다.

        var res = query.Products.Select(m => new
        {
            productID = product.Id,
            categoryID = m.ProductCategory.Select(s => s.Category.ID).ToList(),
        }).ToList();


답변