如何将字符串linq与子查询与另一个linq与子查询进行比较

时间:2014-04-22 07:40:17

标签: sql asp.net-mvc linq linq-to-sql

我有4张桌子:

Position表:

|     Position  |  PositionId  | 
|     driver    |     1        | 
|     clerk     |     2        |

position Skill表:

|  SkillId  |    skill     |     PositionId  |  
|     1     |   driving    |        1        |
|     2     |   drifting   |        1        |

Worker表:

|     Name     |    WorkerId | 
|     John     |     1       |
|     alex     |     2       |

Worker skill表:

|     skillId |    skill     |     WorkerId   |
|     1       |   driving    |        1       |
|     2       |   drifting   |        1       |

join position表和position Skill表 和worker表格worker skill

我遇到的问题是如何比较两个joined表格以获得

的结果?

例如:

我需要知道谁worker拥有该职位所具备的所有特定技能

像:

我选择positionId为1的位置,并skillname drivingdrifting 我需要Workerskills drivingdrifting

相同的var PositionsWithSkills = (from a in db.Client_Customer_Position where a.ID == position select new { PositionID = a.ID, RequiredSkills = (from b in db.Client_Customer_Position_Skills where b.ClientCusPosId == a.ID select b.SkillName) }).ToList(); var WorkersWithSkills = (from x in db.Workers select new { workerId = x.ID, Skills = (from y in db.Worker_Skills where y.Worker_ID == x.ID select y.SkillName) }).ToList(); var PositionWithSkilledWorkers = (from pos in PositionsWithSkills select new { PositionId = pos.PositionID, Workers = (from worker in WorkersWithSkills where pos.RequiredSkills.All(skill => worker.Skills.Any(workerSkill => workerSkill == skill)) select worker.workerId) }).ToList(); 到目前为止我得到了这个:

query

两个worker id效果很好..但最后一个查询我必须比较两个查询= ..我不能得到stored proc 我可以将其转为{{1}}吗?

5 个答案:

答案 0 :(得分:1)

抱歉,如果错了。我从你的问题中得知的是你希望工人名单满足你所通过职位的所有技能。如果这是你想要的,你可以试试这个:

 var workerWithallSkill = (from u in db.workerList join x in db.workerSkillList on    u.WorkerId equals x.WorkerId 
 where ((from y in db.workerSkillList where y.WorkerId == u.WorkerId select y).Count() == (from p in db.positionSkillList where p.PositionId == 1("pass your positionId here") select p).Count()) 
select u).ToList().Distinct();

或者如果你想使用lambda表达式,你可以使用这个

var workerWithallSkill = (from u in workerList join x in workerSkillList on u.WorkerId equals x.WorkerId where (workerSkillList.Where(y=> y.WorkerId == u.WorkerId).Count() ==  positionSkillList.Where(p=>p.PositionId == 1).Count()) select u).ToList().Distinct();

要获得更多理解,您可以尝试以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication8
{
    class Program
    {
        static void Main(string[] args)
        {

            IList<Position> positionList = new List<Position>() { 
                new Position(){ position="Driver", PositionId=1}
                ,new Position(){ position="clerk", PositionId=2}
              };


            IList<PositionSkill> positionSkillList = new List<PositionSkill>() {
                new PositionSkill(){ Skill = "driving",skillid = 1,PositionId = 1}
               ,new PositionSkill(){ Skill = "drifting",skillid = 2,PositionId = 1}
            };

            IList<Worker> workerList = new List<Worker>() {
             new Worker(){ name = "John",WorkerId = 1}
            ,new Worker(){ name = "alex",WorkerId = 2}
            };

            IList<WorkerSkill> workerSkillList = new List<WorkerSkill>(){
                new WorkerSkill(){Skill = "driving",skillid = 1,WorkerId = 2}
                , new WorkerSkill(){Skill = "drifting",skillid = 2,WorkerId = 2}
            };

            var workerWithallSkill = (from u in workerList join x in workerSkillList on u.WorkerId equals x.WorkerId where (workerSkillList.Where(y => y.WorkerId == u.WorkerId).Count() == positionSkillList.Where(p => p.PositionId == 1).Count()) select u).ToList().Distinct();

            foreach (var worker in workerWithallSkill)
            {
                Console.WriteLine(worker.name);
            }

            Console.ReadLine();

        }
    }


    public class Position
    {
        public string position { get; set; }
        public int PositionId { get; set; }
    }

    public class PositionSkill
    {
        public int skillid { get; set; }
        public string Skill { get; set; }
        public int PositionId { get; set; }
    }

    public class Worker
    {
        public string name { get; set; }
        public int WorkerId { get; set; }
    }

    public class WorkerSkill
    {
        public int skillid { get; set; }
        public string Skill { get; set; }
        public int WorkerId { get; set; }
    }

}

如果工人具有来自不同职位的技能,则上述代码将无效,如果是这样,请尝试下面的代码:

var WorkerPositionSkill = from p in db.positionSkillList join q in db.workerSkillList on p.skillid equals q.skillid select new { posSkill = p, workerSkill = q };

 var workerWithallSkill = (from u in db.workerList join x in db.workerSkillList on u.WorkerId equals x.WorkerId where (WorkerPositionSkill.Where(y => y.workerSkill.WorkerId == u.WorkerId && y.posSkill.PositionId == 1).Count() == db.positionSkillList.Where(p => p.PositionId == 1).Count()) select u).ToList().Distinct();

答案 1 :(得分:0)

  var PositionsWithSkills = (from a in Positions select new {
      PositionID = a.PositionId,
      RequiredSkills = (from b in PositionSkills where b.PositionId == a.PositionId select b.skillId).ToList()
  }).ToList();

  var WorkersWithSkills = (from x in Workers select new {
      Name = x.Name,
      Skills = (from y in WorkerSkills where y.WorkerId == x.WorkerID select y.skillId).ToList()
  }).ToList();

  var PositionWithSkilledWorkers = (from pos in PositionsWithSkills select new {
      PositionId = pos.PositionID,
      Workers = (from worker in WorkersWithSkills where pos.RequiredSkills.All(skill => worker.Skills.Any(workerSkill => workerSkill == skill)) select worker.Name).ToList()
  }).ToList();

答案 2 :(得分:0)

这极不可能与Linq To SQL一起使用,因为......它是#$%&amp;的一大堆热闹。但是这个Linq查询应该给出一个足够神奇的IQueryProvider给出正确的SQL。我看到一些非常神奇的东西来自实体框架。

var PositionsWithSkills = from a in db.Client_Customer_Position
                          where a.ID == position
                          select new
                          {
                               PositionID = a.ID,
                               RequiredSkills = (from b in db.Client_Customer_Position_Skills
                                                 where b.ClientCusPosId == a.ID
                                                 select b.SkillName)
                          };

var WorkersWithSkills =  from x in db.Workers
                         select new
                         {
                             workerId = x.ID,
                             Skills = (from y in db.Worker_Skills
                                       where y.Worker_ID == x.ID
                                       select y.SkillName)
                         };

var PositionWithSkilledWorkers = from pos in PositionsWithSkills
                                 from worker in WorkersWithSkills
                                 where pos.RequiredSkill.All(worker.Skills.Contains)
                                 group worker.Name by pos.PositionID;

PS请学会使用关联而不是加入/在哪里。如果您打算使用join / where,那么您也可以使用SQL。

答案 3 :(得分:0)

我认为,您的数据库表格设计不正确... 你需要worker skillposition skill之间的关系,我认为你的表必须这样设计:

技能表:技能ID,技能

职位表:PositionID,职位

PositionSkill表:ID,SkillID,PositionID

工作表:WorkerID,名称

WorkerSkill表:ID,SkillID,WorkerID

但通过这种方式设计表格,如果假设skill字段(技能说明)在worker skillposition skill中相同,我们可以将其用作关系,并且您的查询可以是这样的:

// skills of specific position
var PositionSkills = Context.PositionSkill.Where(u => u.PositionId == 1);

var WorkersWithSkills = Context.Worker
    .Join(Context.WorkerSkill,
          worker => worker.WorkerId,
          workerSkill => workerSkill.WorkerId,
          (worker, workerSkill) => new { worker, workerSkill })
    .GroupBy(u => u.worker)
    .Select(u => new
    {
       u.Key.WorkerId,
       u.Key.Name,
       Skills = u.Select(t => t.workerSkill.skill)
    });

var SkilledWorkers = WorkersWithSkills
    .Where(u => PositionSkills.All(t => u.Skills.Contains(t.skill)))
    .ToList();

如果您不更改数据库的表格,可以在join tableposition skill之间添加worker skill,如:

WorkerPositionSkill:PositionSkillID,WorkerSkillID

答案 4 :(得分:0)

这是一个 LinqPad程序,它返回结果{Worker = John,Position = Driver}。如果我了解您的要求,您希望找到满足工人具备职位= 1所需技能的条件的工人,这就是驾驶和漂移技能。查询返回以下两行[{worker = John,Position = Driver},{worker = John,Position = Driver}]。我不得不使用distinct来显示一次。两排的原因是他满足了驾驶和漂移工作技能。如果该职位需要工人遇到的4种技能,则会有4个重复的行。这个问题的独特修复。希望这可以帮助你。

我在LinqPad中创建了这个解决方案,这是一个很好的工具,包含数百个记录良好的linq查询示例。

void Main()
{
    // Table Setup
    // ************
    var position = new List<Position>();
    position.Add(new Position { Id = 1, Name = "driver" });
    position.Add(new Position { Id = 2, Name = "clerk" });

    var positionSkill = new List<PositionSkill>();
    positionSkill.Add(new PositionSkill { Id = 1, Skill = "driving", PositionId = 1 });
    positionSkill.Add(new PositionSkill { Id = 2, Skill = "drifting", PositionId = 1 });

    var worker = new List<Worker>();
    worker.Add(new Worker { Id = 1, Name = "John" });
    worker.Add(new Worker { Id = 2, Name = "alex" });

    var workerSkill = new List<WorkerSkill>();
    workerSkill.Add(new WorkerSkill { Id = 1, Skill = "driving", WorkerId = 1 });
    workerSkill.Add(new WorkerSkill { Id = 2, Skill = "drifting", WorkerId = 1 });  

    // The Query
    // *********
    var positionValue = 1;

        var r = from p in position
                join ps in positionSkill on p.Id equals ps.PositionId
                join ws in workerSkill on ps.Skill equals ws.Skill
                join w in worker on ws.WorkerId equals w.Id
                where p.Id == positionValue
                select new {
                    PositionName = p.Name,
                    WorkerName = w.Name
                };

    // Get Distinct Names           
    r.Distinct().Dump();


}

// Define other methods and classes here
    public class Position
    {
        public int Id { get; set; }
        public string Name { get; set; }

    }


    public class PositionSkill
    {
        public int Id { get; set; }
        public string Skill { get; set; }
        public int PositionId { get; set; }

    }



    public class Worker
    {
        public int Id { get; set; }
        public string Name { get; set; }

    }


    public class WorkerSkill
    {
        public int Id { get; set; }
        public string Skill { get; set; }
        public int WorkerId { get; set; }

    }