将SQL转换为Linq左连接,返回null

时间:2012-02-07 04:35:49

标签: c# .net sql linq

如何将此SQL正确转换为linq

select  t1.ProgramID
from Program t1 LEFT JOIN ProgramLocation t2 ON  t1.ProgramID = t2.ProgramID 
where t2.ProgramID IS NULL

我试过但是没有用

var progy = (
             from u in db.ProgramLocations join b in db.Programs
             on u.ProgramID equals b.ProgramID into yG 
             from y1 in yG.DefaultIfEmpty() 
             where u.ProgramID == null
             where u.ProgramID == null 
             select u.ProgramID
            ).ToList();

感谢

5 个答案:

答案 0 :(得分:93)

您希望.DefaultIfEmpty使用var query = from p in Programs join pl in ProgramLocations on p.ProgramID equals pl.ProgramID into pp from pl in pp.DefaultIfEmpty() where pl == null select p;

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

namespace LinqTest
{
    class LinqProgram
    {
        public class Program
        {
            public int ProgramID { get; set; }
            public string ProgramName { get; set; }
        }

        public class ProgramLocation
        {
            public int ProgramLocationID { get; set; }
            public int ProgramID { get; set; }
            public string ProgramLocationName { get; set; }
        }

        public static List<Program> Programs = new List<Program>();
        public static List<ProgramLocation> ProgramLocations = new List<ProgramLocation>();

        static void Main(string[] args)
        {
            FillTestData();

            var query = from p in Programs
                        join pl in ProgramLocations
                            on p.ProgramID equals pl.ProgramID into pp
                        from pl in pp.DefaultIfEmpty()
                        where pl == null
                        select p;

            foreach (var r in query)
            {
                Console.WriteLine("{0}: {1}", r.ProgramID, r.ProgramName);
            }

            Console.ReadLine();
        }

        private static void FillTestData()
        {
            var p = new Program()
            {
                ProgramID = Programs.Count + 1,
                ProgramName = "Scary Lesson"
            };
            var pl = new ProgramLocation()
            {
                ProgramLocationID = ProgramLocations.Count + 1,
                ProgramID = p.ProgramID,
                ProgramLocationName = "Haunted House"
            };
            Programs.Add(p);
            ProgramLocations.Add(pl);

            p = new Program()
            {
                ProgramID = Programs.Count + 1,
                ProgramName = "Terrifying Teachings"
            };

            pl = new ProgramLocation()
            {
                ProgramLocationID = ProgramLocations.Count + 1,
                ProgramID = p.ProgramID,
                ProgramLocationName = "Mystical Mansion"
            };
            Programs.Add(p);
            ProgramLocations.Add(pl);

            p = new Program()
            {
                ProgramID = Programs.Count + 1,
                ProgramName = "Unassociated Program"
            };
            Programs.Add(p);
        }
    }
}

这是一个包含一些模拟数据对象的完整工作示例:

{{1}}

答案 1 :(得分:2)

试试这个

  var progy = (
         from u in db.ProgramLocations join b in db.Programs
         on u.ProgramID equals b.ProgramID into yG 
         from y1 in yG.DefaultIfEmpty() 
         where y1 == null
         select u.ProgramID
        ).ToList();

您可以查看this post on MSDN

希望这适合你。

答案 2 :(得分:2)

你可以使用除了吗?

var progy = (
  from u in db.ProgramLocations
  select u.ProgramID
).Except(from b in db.Programs select b.ProgramID);

答案 3 :(得分:0)

SELECT pfa.PetID, pt.PetTypeDesc, pfa.petname, pf.PetOwner, pf.remarks, pat.AdoptedBy
    FROM dbo.PetForAdoption pfa
    JOIN dbo.PetAdoptionTran pat
    ON pfa.PetID = pat.PetID
    JOIN dbo.PetTypes pt 
    ON pfa.PetTypeID = pt.PetTypeID
    JOIN dbo.PetProfile pf
    ON pfa.PetID = pf.PetID
    ORDER BY pt.PetTypeDesc

答案 4 :(得分:0)

我现在遇到了这个问题,必须使用简洁的 SQL 并使其以非常优化的方式工作。

林克:

var recs=from programs in db.Programs
         from locations in db.ProgramLocations.where(x=> x.ProgramID == programs.ProgramID).DefaultIfEmpty()
         where locations.ProgramID == null  //Compiler creates a warning because int will never be null, but it works and creates outer left join
         select programs.ProgramID;

结果 SQL:

SELECT 
"Extent1"."ProgramID" AS "ProgramID"
FROM "DBO"."Program" "Extent1"
LEFT OUTER JOIN "DBO"."ProgramLocation" "Extent2" ON "Extent2"."ProgramID" = "Extent1"."ProgramID"
WHERE ("Extent2"."ProgramID" IS NULL)

如果您有多个连接条件,这也适用,并且也适用于多个左连接

ps。我在 Oracle 中使用 EF,所以不确定 E 的 SQLServer 提供程序是否会略有不同