使用LINQ to SQL查询连接列表

8

我有一个 MyObject 列表,长这样:

public class MyObject{
  public int FruitID {get;set;}
  public string FruitName {get;set;}
}

List<MyObject> TheList = new List<MyObject>();

这个列表是通过linq-to-sql查询生成的。我想在这个列表和一个包含FruitID作为外键的表之间创建一个连接。
HarvestTimes表长这样:
FruitID   |   HarvestDatetime  |   RipeFactor
   3      |        3/4/2011    |       2
   3      |        4/5/2011    |       4
   3      |        5/5/2011    |       3
   4      |        3/21/2011   |       2
   4      |        4/10/2011   |       2
   4      |        5/10/2011   |       2

这是我目前的翻译内容:

这是我目前的进展:

var TheQuery = (from list in TheList
                join fruit in MyDC.HarvestTimes on
                list.FruitID equals fruit.FruitID
                where ....
                select new MyObject{... }).ToList();

我在Where子句方面遇到了一些问题。如何仅获取RipeFactor始终为2的水果。例如,Fruit 3的RipeFactor为2,但同时还有4,而只有Fruit4仅有2。我尝试使用Contains,但两种水果都出现了。

感谢您的建议。


不确定是否可能,但可以尝试按FruitID和Ripe factor分组,然后计算每个FruitID组中的行数,如果计数为1且Ripe factor符合要求,则选择它... - atoMerz
TheList是否由与HarvestTimes存在的DataContext填充? - Magnus
2个回答

3
假设表HaverstTime和Fruit之间存在关联:
var TheQuery = MyDC.HarvestTimes
    .Where(p => TheList.Select(q => q.FruitID).Contains(p.FruitID))
    .GroupBy(p => p.Fruit)
    .Where(p => p.All(q => q.RipeFactor == 2))
    .Select(p => p.Key);

这将创建一个 IEnumerable<Fruit>,我认为可以很容易地转换为 MyObject。
更新: 哎呀,我忘记添加 TheList.Select(q => q.FruitID)。这就是为什么它没有编译通过。 抱歉 =)
更新2: 做同样的事情,考虑 Ripefactor = 2 和 3。
var TheQuery = MyDC.HarvestTimes
    .Where(p => TheList.Select(q => q.FruitID).Contains(p.FruitID))
    .GroupBy(p => p.Fruit)
    .Where(p => p.All(q => q.RipeFactor == 2 || q.RipeFactor == 3))
    .Select(p => p.Key);

应该是 .GroupBy(p => p.FruitID) 吗? - frenchie
由于某些原因,“.Where(p => TheList.Contains(p.FruitID))”语句被标为红色下划线。 - frenchie
这要看情况。我以为你想选择Fruit对象,而不是FruitID。在这种情况下,你可以使用GroupBy(p => p.FruitID),这也应该可以工作。 - Francisco
好的,如果我想选择RipeFactor,其中它只是2和3(但从不是1、4或任何其他值),该怎么办? - frenchie

1

我认为这会起作用

var fruit = (from list in TheList
             join fruit in
               (from fr in MyDc.HarvestTimes
                group fr by fr.FruitID into fg
                where !fg.Any(f => f.RipeFactor != 2)
                select fg)
             on list.FruitID equals fruit.Key
             select new MyObject{... }).ToList();

更新 - 如果你只想返回不重复的FruitIDs列表,你需要选择fg.Key而不是fg
var fruit = (from list in TheList
             join fruit in
               (from fr in MyDc.HarvestTimes
                group fr by fr.FruitID into fg
                where !fg.Any(f => f.RipeFactor != 2)
                select fg.Key)
              on list.FruitID equals fruit
              select new MyObject{... }).ToList();

是的,从这个意义上讲它是有效的,因为它只返回 Fruit4。我再次查看了它,然后意识到它返回了所有 Fruit4 记录而不仅仅是其中一个。我想我在那方面没有表达清楚,我的错。在这种情况下,用 .Single 会起作用吗? - frenchie
@frenchie - 已更新答案。这是您要找的吗? - Aducci
我会选择带有重复项的那个,并使用 Linq-to-object 查询删除重复项。感谢您的帮助,如果您找出为什么会显示重复项,请告诉我。 - frenchie
快速追踪:如果我希望得到RipeFactor只为2和3的结果,应该使用这个条件吗:where !fg.Any(f => f.RipeFactor != 2 && f => f.RipeFactor != 3)? - frenchie
@frenchie - 不确定为什么会显示重复项。是的,你是正确的。 - Aducci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接