使用LINQ基于联接表的空值加入后从表中获取数据

时间:2017-01-08 08:12:14

标签: sql-server asp.net-mvc linq join asp.net-web-api

我有一些像"Job" "AppliedJob" "JobOffer" "Contract" "Employeer"这样的表格 enter image description here

描述:当雇员发布工作时,它存储在" Job"表与他的身份证。如果自由职业者适用于该工作,则将其存储在" AppliedJob"表与他的身份证。然后,员工查看应用程序并向自由职业者发送要约,并将其存储在" JobOffer"表。如果自由职业者接受要约,则将其存储在"合同"表。首先是"合同"存储ContractID,OfferID和StratDate,并将CompletedDate存储为null。合同完成后,将使用日期修改CompletedDate字段。 想:我想要退回所有没有完成合同的工作 我试过了:

 [HttpGet]
    [Route("api/PrivateApi/GetEmployeerPostedJob/")]
    public object GetEmployeerPostedJob(int id)
    {

        var data = (from j in db.Jobs
                    where j.EmployeerID == id
                    join apl in db.AppliedJobs
                    on j.JobID equals apl.JobID
                    join o in db.JobOffers
                    on apl.AppliedJobID equals o.AppliedJobID
                    join con in db.Contracts
                    on o.OfferID equals con.OfferID
                    where con.CompletedDate == null



                    select new
                    {
                        j.JobTitle,
                        j.JobID,
                        j.Budget,
                        j.Deadline,
                        j.Employeer,
                        j.JobDetails,
                        j.PublishDate,
                        j.ReqSkill,
                        j.NoOFFreelancer,
                        j.Preference,
                        Category1=j.Category,
                       totalAppliedFreelancer=(from aple in db.AppliedJobs where j.JobID ==aple.JobID select aple).Count(),

                        Category = (from gg in db.Categories where gg.CategoryID == j.Category select gg.CategoryName).FirstOrDefault()

                    }).ToList();


        return data.AsEnumerable();
    }

但它没有返回任何工作。 如何获得尚未完成的所有作业(合同表中的CompletedDate == null)?

2 个答案:

答案 0 :(得分:2)

  

我想在他的页面上显示雇员张贴的工作,但只显示那些未完成的工作

以上(涉及一对多的关系)可以解释为

返回未完成合同

的所有工作

在您编写查询的方式中,除了可能的数据重复之外,它还回答了问题

使用现有但未完成的合同返回所有作业

即。缺少没有申请工作的工作,没有提供申请工作,没有提供合同。

正确的查询将是这样的:

from job in db.Jobs
where job.EmployeerID == id
join jobContract in (
   from appliedJob in db.AppliedJobs
   join offer in db.JobOffers on appliedJob.AppliedJobID equals offer.AppliedJobID
   join contract in db.Contracts on offer.OfferID equals contract.OfferID
   select new { appliedJob, offer, contract }
) on job.JobID equals jobContract.appliedJob.JobID into jobContracts
where !jobContracts.Any(jobContract => jobContract.contract.CompletedDate != null)
select ...

使用navigation properties可以进一步简化查询,但由于我在AppliedJobJobOffer之间没有看到导航属性,因此我将为您留下该信息。

更新:以下是带导航属性的相同查询(简化后我认为不需要join运算符):

from job in db.Jobs
let completedContracts =
    from appliedJob in job.AppliedJobs
    from offer in appliedJob.JobOffers
    from contract in offer.Contracts
    where contract.CompletedDate != null
    select contract
where !completedContracts.Any()
select ...

答案 1 :(得分:0)

此LINQ查询在实时服务器(sql-2008)上不起作用但在本地VS 2013上有效。如果我的实时数据库第一次出现空白,是否有任何错误? @Ivan Stoev

公共对象BrowseJobs()         {

        var skills = db.Skills.ToDictionary(d => d.SkillID, n => n.SkillName);

        var jobData = (from j in db.Jobs where j.Preference==2
                       //from cj in j.ClosedJobs.DefaultIfEmpty() 
                       join cj in db.ClosedJobs.DefaultIfEmpty()
                       on j.JobID equals cj.JobID into closedJob
                       where !closedJob.Any()
                       join c in db.Categories on j.Category equals c.CategoryID

                       join jobContract in
                           (
                               from appliedJob in db.AppliedJobs.DefaultIfEmpty()
                               from offer in appliedJob.JobOffers.DefaultIfEmpty() 
                               from contract in db.Contracts.DefaultIfEmpty()
                               select new { appliedJob, offer, contract }
                               ).DefaultIfEmpty()
                       on j.JobID equals jobContract.appliedJob.JobID into jobContracts
                       where !jobContracts.Any(jobContract => jobContract.contract.CompletedDate != null)

                       select new
                       {

                           JobTitle = j.JobTitle,
                           JobID = j.JobID,
                           ReqSkillCommaSeperated = j.ReqSkill,
                           Category = c.CategoryName,
                           Budget=j.Budget,
                           Deadline=j.Deadline, 
                           JobDetails=j.JobDetails,
                           PublishDate=j.PublishDate,
                           TotalApplied=(from ap in db.AppliedJobs where j.JobID == ap.JobID select ap.AppliedJobID).DefaultIfEmpty().Count()

                       }).AsEnumerable()
            .Select(x => new
            {
                JobID = x.JobID,
                JobTitle = x.JobTitle,
                Category = x.Category,
                Budget = x.Budget,
                Deadline = x.Deadline,
                JobDetails = x.JobDetails,
                PublishDate = x.PublishDate,
                SkillNames = GetSkillName(x.ReqSkillCommaSeperated, skills),
                TotalApplied = (from ap in db.AppliedJobs where x.JobID == ap.JobID select ap.AppliedJobID).DefaultIfEmpty().Count()
            }).ToList();


        return jobData.AsEnumerable();
    }