LINQ LEFT JOIN使用LIST <string> </string>

时间:2012-07-10 00:35:34

标签: asp.net-mvc-3 linq linq-to-entities

假设您有一个ID列表:

string str = "82174F2000000, 82174F2000001, 82174F2000002, 82174F2000003, 82174F2000004, 82174F2000005";

你这样做:

var tids = new List<string>(str.Replace(", ", ",").Split(','));
var tntable = tids.AsQueryable();

并且您想将它与具有左连接的表进行比较:

var line = from c in db.Ctable
 join l  in tntable on c.CarID equals l.CarID into c_j
  from l in c_j.DefaultIfEmpty()
  select new
  {
 Name =  c.OwnerName,
 Hours = c.Hours
  };

看起来tntable没有名为'CarID'的字段。

有人可以帮忙吗?

这适用于LINQ to Entity。

我见过这个:

How to compare List<String> to DB Table using LINQ

但不知道要做LEFT JOIN。

TIA!

我知道这很长;但感谢阅读。

更新MichaC:

在CTable的数据库中,我们有这些CarID:

CarID
_____
82174F2000000
82174F2000001
82174F2000002
82174F2000003

我们只是说表(tntable)包含分解为记录的字符串:

CarID
_____
82174F2000000
82174F2000001
82174F2000002
82174F2000003
82174F2000004
82174F2000005

所以,像这样的LEFT JOIN:

SELECT C.CarID, T.CarID
FROM CTable C
LEFT JOIN tntable T ON C.CarID = T.CarID

会让你这样:

T.CarID         C.CarID
_______         _______
82174F2000000   82174F2000000
82174F2000001   82174F2000001
82174F2000002   82174F2000002
82174F2000003   82174F2000003
82174F2000004   NULL
82174F2000005   NULL 

3 个答案:

答案 0 :(得分:1)

如果我正在阅读您的问题,看起来您希望根据ID列表进行过滤,而不是执行左连接。我想你想要这样的东西:

var line = from c in db.Ctable
           where tntable.Contains(c.CarID)
           select new 
           {
              Name =  c.OwnerName,
              Hours = c.Hours
           };

更新:您可以将包含检查移动到select语句以返回所有内容。

var line = from c in db.Ctable
           select new 
           {
              IsMatch = tntable.Contains(c.CarID),
              Name =  c.OwnerName,
              Hours = c.Hours
           };

更新2:好的,这个怎么样。使用我的原始文件从SQL中提取相关项,然后使用Linq to Objects以您希望的方式实际构建列表。 .ToList()强制它进行SQL查询。您也可以使用.AsEnumerable()。

var filtered = from c in db.Ctable
           where tntable.Contains(c.CarID)
           select new 
           {
              CarID = c.CarID,
              Name =  c.OwnerName,
              Hours = c.Hours
           };

var line = from x in tntable
           join i in filtered.ToList() on x equals u.CarID into i_match
           from i in i_match.DefaultIfEmpty()
           select { x, i };

答案 1 :(得分:0)

即使在tntable中找不到ID,您还是希望null仍然为ctable中的每个ID选择一个对象?如果我理解正确的话,我相信这会给你带来理想的效果。

var desired = from l in tntable
              join c in ctable on l equals c.CarID into lj
              from c in lj.DefaultIfEmpty()
              select
                  new
                      {
                          Name = c == null ? null : c.OwnerName,
                          Hours = c == null ? (int?)null : c.Hours
                      };

答案 2 :(得分:0)

看看这个:

string str = "Pat, Boots";
var names = new List<string>(str.Replace(", ", ",").Split(',')).AsQueryable();

Pet defaultPet = new Pet { Name = "Default Pet", Age = -1 };

List<Pet> pets1 = new List<Pet>{ 
            new Pet { Name="Barley", Age=8 },
            new Pet { Name="Boots", Age=4 },
            new Pet { Name="Whiskers", Age=1 } 
    };

var pets = from name in names
            join pet in pets1 on name equals pet.Name into gj
            from subpet in gj.DefaultIfEmpty(defaultPet)
            select new { Name = name, Age = subpet.Age };


foreach(var newPet in pets) {
    Console.WriteLine("\nName: {0}, Age: {1} ", newPet.Name, newPet.Age );
}

这会产生:

Name: Pat, Age: -1
Name: Boots, Age: 4

如果这不符合您的要求,请仔细查看How to: Perform Left Outer Joins (C# Programming Guide) on MSDN

我使用了上面的链接和MSDN的DefaultIfEmpty()帮助页面。