代码之家  ›  专栏  ›  技术社区  ›  John Landheer

实体框架和多对多查询不可用?

  •  16
  • John Landheer  · 技术社区  · 17 年前

    EDIT: Tables:
    
    Person (personid, name)
    
    Personlocation (personid, locationid)
    
    Location (locationid, description)
    
    Personrole (personid, roleid)
    
    Role (roleid, description)
    

    我如何创建一个查询,为我提供给定位置上具有给定角色的所有人员?

    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'
    

    我找过了,但似乎找不到合适的答案 易于理解的 解决方案

    4 回复  |  直到 17 年前
        1
  •  29
  •   stoto    16 年前

    因为它在EFV1中,我们将 角色

    解决方案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();  
    

    而且它的性能还可以。

    这里有一些分类。

       // 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();
    

     //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();
    

        2
  •  11
  •   giuice    17 年前

    在Lambda:

        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)
    

    朱利亚诺·莱姆斯

        3
  •  1
  •   Jason    16 年前

    找到了有关这方面的更多信息,以及实体处理多对多的方式和原因:

    ASP.NET Blog - Many to Many Mappings in Entity Framework

        4
  •  0
  •   John Landheer    17 年前

    推荐文章