2

假设我有一个如下列表:

 List<R> lstR = GetR();

现在我想要一个 Linq 语句来获取分配给的菜单R,我通过使用循环然后使用 Linq 来获取菜单来实现这一点,如下所示:

 List<int> ids = new List<int>();
 foreach (R r in lstR)
 {
   ids.Add(r.Id);
 }

 menu = (from s in db.Menu
         where ids.Contains(s.R.Id)
         select s.MenuText).Distinct();

现在据我所知,上面是两个循环(Linq 正在使用内部循环)。我能否将这两个语句结合起来,即不执行第一个循环来获取 id?

4

5 回答 5

3

无论是内存数据集(Linq-to-Objects)还是数据库中的集合lstR,您都可以这样做:db.MenuIQueryable

menu = 
    (from s in db.Menu
     where lstR.Select(r => r.Id)
               .Contains(s.R.Id)
     select s.MenuText)
    .Distinct();

或这个:

menu = 
    (from s in db.Menu
     join r in lstR on s.R.Id equals r.Id
     select s.MenuText)
    .Distinct();

但是,由于List<R>存在于内存中并且db.MenuIQueryable,因此您的选择是有限的。您可以实现db.MenuIEnumerable,因此您可以在内存中处理它:

List<R> lstR = GetR();
menu = 
    (from s in db.Menu.AsEnumerable()
     join r in lstR on s.R.Id equals r.Id
     select s.MenuText)
    .Distinct();

但是,如果有很多记录,这可能会很昂贵。最好做这样的事情,诚然,这看起来与你已经拥有的没什么不同:

List<R> lstR = GetR();
var ids = lstR.Select(r => r.Id).ToList(); // or .ToArray();
menu = 
    (from s in db.Menu
     where ids.Contains(s.R.Id)
     select s.MenuText)
    .Distinct();

但事实上,最好的选择是看看你是否可以重构GetR,以便它IQueryable<R>从你的数据库中返回一个。这样您就可以同时使用前两个选项,而无需先将任何集合具体化到内存中。顺便说一句,一旦你完成了这些设置了导航属性,你可能会做这样的事情:

IQueryable<R> lstR = GetR();
menu = 
    (from r in lstR
     from s in r.Menus
     select s.MenuText)
    .Distinct();
于 2013-09-12T15:33:30.557 回答
2

可以这样做。

menu = (from s in db.Menu
        where lstR.Select(item => item.Id).Contains(s.R.Id)
        select s.MenuText).Distinct();

但我不会将这两个语句结合起来,因为如果你使用 HashSet 它会加快速度:

var ids = new HashSet<int>(lstR);

menu = (from s in db.Menu
     where ids.Contains(s.R.Id)
     select s.MenuText).Distinct();

我猜这会更快。第一个问题是,列表中的每一个都sdb.Menu迭代以创建一个 id 的列表select()

于 2013-09-12T15:32:44.820 回答
1
menu = db.Menu.Where(s => GetR().Select(r => r.Id).Contains(s.R.Id))
                     .Select(s => s.MenuText)
                     .Distinct();

但它会很复杂。如果你这样写会更好

        var ids = GetR().Select(r => r.Id);

        menu = db.Menu.Where(s => ids.Contains(s.R.Id))
                      .Select(s => s.MenuText)
                      .Distinct();
于 2013-09-12T15:46:59.670 回答
1

您可以使用 linq 投影方法Select()

ids = lstR.Select(p => p.Id);
于 2013-09-12T15:32:19.090 回答
0

使用加入

var result = (from s in db.Menu
              join r in lstR on s.Id equals r.ID
              select s.MenuText).Distinct();
于 2013-09-12T15:37:02.797 回答