엔터티 프레임 워크와 많은 쿼리를 사용할 수 없습니까?

.net entity-framework many-to-many

문제

EF를 시도하고 있으며 많은 관계를 기반으로 많은 필터링을 수행합니다. 예를 들어, 사람, 위치 및 두 사람을 연결하는 사람 위치 테이블이 있습니다. 나는 또한 역할과 personrole 테이블이 있습니다.

EDIT: Tables:

Person (personid, name)

Personlocation (personid, locationid)

Location (locationid, description)

Personrole (personid, roleid)

Role (roleid, description)

EF는 사람, 역할 및 위치 엔티티를 제공 할 것입니다. 편집 : EF는 personlocation 및 personrole 엔티티 유형을 생성하지 않습니다 때문에, 쿼리에서 사용할 수 없습니다.

특정 위치의 모든 사람에게 주어진 역할을 부여하는 쿼리를 어떻게 만듭니 까?

SQL에서는 쿼리가

select p.*
from persons as p
join personlocations as pl on p.personid=pl.personid
join locations       as l  on pl.locationid=l.locationid
join personroles     as pr on p.personid=pr.personid
join roles           as r  on pr.roleid=r.roleid
where r.description='Student' and l.description='Amsterdam'

나는 보았지만 간단한 해결책을 찾지 못했습니다.

수락 된 답변

람다 :

    var persons = Persons.Where(p=>(p.PersonLocations.Select(ps=>ps.Location)
   .Where(l=>l.Description == "Amsterdam").Count() > 0)
    && (p.PersonRoles.Select(pr=>pr.Role)
   .Where(r=>r.Description == "Student").Count() > 0));

쿼리 결과 :

SELECT [t0].[personId] AS [PersonId], [t0].[description] AS [Description]
FROM [Persons] AS [t0]
WHERE (((
    SELECT COUNT(*)
    FROM [personlocations] AS [t1]
    INNER JOIN [Locations] AS [t2] ON [t2].[locationid] = [t1].[locationid]
    WHERE ([t2].[description] = @p0) AND ([t1].[personid] = [t0].[personId])
    )) > @p1) AND (((
    SELECT COUNT(*)
    FROM [PersonRoles] AS [t3]
    INNER JOIN [Roles] AS [t4] ON [t4].[roleid] = [t3].[roleid]
    WHERE ([t4].[description] = @p2) AND ([t3].[personid] = [t0].[personId])
    )) > @p3)

포함 () 사용 :

var persons = Persons
            .Where(p=>(p.Personlocations.Select(ps=>ps.Location)
            .Select(l=>l.Description).Contains("Amsterdam")) && 
            (p.PersonRoles.Select(pr=>pr.Role)
            .Select(r=>r.Description).Contains("Student")));

쿼리 결과 :

SELECT [t0].[personId] AS [PersonId], [t0].[description] AS [Description]
FROM [Persons] AS [t0]
WHERE (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [personlocations] AS [t1]
    INNER JOIN [Locations] AS [t2] ON [t2].[locationid] = [t1].[locationid]
    WHERE ([t2].[description] = @p0) AND ([t1].[personid] = [t0].[personId])
    )) AND (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [PersonRoles] AS [t3]
    INNER JOIN [Roles] AS [t4] ON [t4].[roleid] = [t3].[roleid]
    WHERE ([t4].[description] = @p1) AND ([t3].[personid] = [t0].[personId])
    ))

join () 사용 :

var persons = Persons
        .Join(Personlocations, p=>p.PersonId, ps=>ps.Personid,
(p,ps) => new {p,ps})
.Where(a => a.ps.Location.Description =="Amsterdam")
        .Join(PersonRoles,
pr=> pr.p.PersonId, r=>r.Personid,(pr,r) => new {pr.p,r})
.Where(a=>a.r.Role.Description=="Student")
        .Select(p=> new {p.p});

쿼리 결과 :

SELECT [t0].[personId] AS [PersonId], [t0].[description] AS [Description]
FROM [Persons] AS [t0]
INNER JOIN [personlocations] AS [t1] ON [t0].[personId] = [t1].[personid]
INNER JOIN [Locations] AS [t2] ON [t2].[locationid] = [t1].[locationid]
INNER JOIN [PersonRoles] AS [t3] ON [t0].[personId] = [t3].[personid]
INNER JOIN [Roles] AS [t4] ON [t4].[roleid] = [t3].[roleid]
WHERE ([t4].[description] = @p0) AND ([t2].[description] = @p1)

큰 데이터 일수록 테스트가 더 빠를 수도 있습니다.

행운을 빕니다.

줄리아노 레 메스


인기 답변

노트 :

그것이 EF의 V1에이기 때문에, 우리는 PersonLocationPersonRole가 LINQ2SQL이 무엇을 같은 개체로 생성이되지 않습니다 (대답 질문에 적용되지 않습니다 LINQ2SQL 시나리오를 domonstrating 위.)

해결책 1 :

Persons.Include("Role").Include("Location") // Include to load Role and Location
       .Where(p => p.Role.Any(r => r.description == "Student") 
       && p.Location.Any(l => l.description == "Amsterdam")).ToList();  

이것은보기 좋고 간단하지만보기 흉한 SQL 스크립트를 생성하고 성능은 양호합니다.

해결책 2 :

다음은 고장입니다.

   // Find out all persons in the role
   // Return IQuerable<Person> 
  var students = Roles.Where(r => r.description == "Student")
                      .SelectMany(r => r.Person);

  // Find out all persons in the location
  // Return IQuerable<Person>  
  var personsInAmsterdam = Locations.Where(l=> l.description == "Amsterdam")
                                    .SelectMany(l=>l.Person);

  // Find out the intersection that gives us students in Admsterdam.
  // Return List<Person>
     var AdmsterdamStudents = students.Intersect(personsInAmsterdam).ToList();

위의 3 단계를 하나로 결합하십시오.

 //Return List<Person>
 var AdmsterdamStudents = Roles.Where(r => r.description == "Student")
                              .SelectMany(r => r.Person)
                              .Intersect
                              ( 
                                Locations
                                .Where(l=> l.description == "Amsterdam")
                                .SelectMany(l=>l.Person)
                               ).ToList();

일종의 자세한 정보입니다. 그러나 이것은 깨끗한 SQL 쿼리를 생성하고 잘 수행됩니다.



Related

아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.