2012-10-04 21 views
2

我有一个展览场景。asp.net mvc Linq排除其他表中的值

如何从展商视图中显示的下拉列表中排除可用展位列表。

在SQL中我想:

Select StandID, Description from Stand 
Where StandID not in (Select StandID from Exhibitor) 

参展商注册 - 选择从下拉列表中(StandID /展位),他们希望支架按以下模式:

public class Exhibitor 
{ 
    public int ExhibitorID { get; set; } 
    public string CompanyName { get; set; } 
    public string ContactName { get; set; } 
    public int StandID { get; set; } 
    public virtual Stand Stand { get; set; } 
} 

的座模型如下:

public class Stand 
{ 
    public int StandID { get; set; } 
    public string Description { get; set; } 
    public bool Booked { get; set; } 
} 

我可以得到看台的名单如下:

var stands = db.Stands.ToList().Where(s => s.Booked==false) 
      .Select(s => new SelectListItem 
      { 
       Value = s.StandID.ToString(), 
       Text = s.StandNumber + ": " + s.Description + ": " + s.Size + ": £" + s.Rate.ToString() 
      }); 

但是,如何从展位清单中排除(从展商中选择StandID)?

我想:

var booked = db.Exhibitors.Select(s => new { s.StandID }).ToList(); 

然后使用:

var stands = db.Stands.ToList().Where(s => s.Booked==false) 
      .Except(booked) 
      .Select(s => new SelectListItem 
      { 
       Value = s.StandID.ToString(), 
       Text = s.StandNumber + ": " + s.Description + ": " + s.Size + ": £" + s.Rate.ToString() 
      }); 

但没有奏效。

UPDATE

这似乎工作 - 但我不是专家,所以希望如果它的任何建议上;最好的练习方式或不?

var stands = db.Stands.ToList().Where(s => !db.Exhibitors 
.Any(bk => bk.StandID == s.StandID) && s.Booked == false) 
      .Select(s => new SelectListItem 
      { 
       Value = s.StandID.ToString(), 
       Text = s.StandNumber + ": " + s.Description + ": " + s.Size + ": £" + s.Rate.ToString() 
      }); 

感谢您的帮助?

马克

回答

3

使用LINQ的contains()方法

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.contains.aspx

var booked = db.Exhibitors.Select(s => s.StandID).ToList(); 
var stand = db.Stands.Where(s=>s.Booked == false 
             && !booked.Contains(s.StandId) 
       .Select(s => new SelectListItem 
       { 
        Value = s.StandID.ToString(), 
        Text = s.StandNumber + ": " + s.Description + ": " + s.Size + ": £" + s.Rate.ToString() 
       }); 

我看到你更新你的问题的最佳做法,太。你的技术可以做很多优化。首先,了解IEnumerableIQueryable之间的区别。

具体而言,您应该从Stands.ToList().Where()中删除ToList()。通过在Where()之前执行ToList(),您将从数据库中取回所有行,然后在内存中处理它们。这可能是非常昂贵的。如果你执行Stands.Where(...),那么你的过滤将在SQL中完成,只有你想要的行将被返回。

通常,将您的ToList()保存为最后一步,然后主动决定是否需要构建该列表。

+0

嗨 - 我收到错误:错误最好的重载方法匹配'System.Collections.Generic.List .Contains(AnonymousType#1)'有一些无效的参数 – Mark

+0

更新我的答案。您不需要为“预订”列表创建匿名对象。你需要一个列表。 (我刚刚删除了你的新陈述) – BZink

+0

谢谢@BZink - 那也行! – Mark

0

理想的方法是始终创建一个您希望作为输出的模型,将输出映射到该模型并将其返回。这也将有助于客户端获得坚定不移的实施模式。

LINQ中的复杂选择查询在运行中生成,比预先编译的结构良好的存储过程花费更多的时间。如果您期待更快的响应,请考虑这一点。

相关问题