LINQ에서 여러 테이블간에 조인 을 수행하려고합니다 . 다음과 같은 수업이 있습니다.
Product {Id, ProdName, ProdQty}
Category {Id, CatName}
ProductCategory{ProdId, CatId} //association table
그리고 나는 다음과 같은 코드를 사용 (여기서 product
, category
및 productcategory
위 클래스의 인스턴스) :
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();