【问题标题】:asp.net mvc Linq exclude values from other tableasp.net mvc Linq 从其他表中排除值
【发布时间】:2012-09-25 23:04:55
【问题描述】:

我有一个展览场景。

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

在 Sql 中我会:

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

参展商注册 - 并根据以下型号从下拉列表(StandID/Stand)中选择他们想要的展位:

 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; }
}

我可以得到一个 Stands 列表如下:

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()
          });

但是如何从展位列表中排除(从参展商中选择展位 ID)?

我试过了:

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()
          });

但这没有用。

更新

这似乎可行 - 但我不是专家,所以如果它是最佳实践方式,请提供任何建议?

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()
          });

感谢您的帮助?

标记

【问题讨论】:

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


    【解决方案1】:

    使用 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() 保存为最后一步,并主动决定是否需要构建列表。

    【讨论】:

    • 嗨 - 我收到错误:错误“System.Collections.Generic.List.Contains(AnonymousType#1)”的最佳重载方法匹配有一些无效参数
    • 更新了我的答案。您无需为“已预订”列表创建匿名对象。你需要一个列表。 (我刚刚删除了你的新声明)
    • 这帮助我找到了自己的解决方案。谢谢@BZink
    【解决方案2】:

    理想的方式始终是创建一个您想要作为输出的模型,将输出映射到该模型并返回它。这也将帮助客户端获得一个明确的模型来坚持和实施。

    LINQ 中的复杂选择查询也是动态生成的,这比预编译的结构良好的存储过程需要更多时间。如果您希望得到更快的响应,请考虑这一点。

    【讨论】:

      猜你喜欢
      • 2017-09-22
      • 2013-01-08
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 2022-10-20
      • 2018-01-09
      • 2012-12-09
      • 1970-01-01
      相关资源
      最近更新 更多