【问题标题】:Where IN clause in LINQ [duplicate]LINQ中的IN子句[重复]
【发布时间】:2009-06-06 14:08:05
【问题描述】:

如何制作一个类似于 SQL Server 中的 where in 子句?

我自己做了一个,但有人可以改进吗?

    public List<State> Wherein(string listofcountrycodes)
    {
        string[] countrycode = null;
        countrycode = listofcountrycodes.Split(',');
        List<State> statelist = new List<State>();

        for (int i = 0; i < countrycode.Length; i++)
        {
            _states.AddRange(
                 from states in _objdatasources.StateList()
                 where states.CountryCode == countrycode[i].ToString()
                 select new State
                 {
                    StateName  = states.StateName                    

                 });
        }
        return _states;
    }

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    这个表达式应该做你想要实现的。

    dataSource.StateList.Where(s => countryCodes.Contains(s.CountryCode))
    

    【讨论】:

    • 这将比较字符串值,但是 ids 呢??
    • @JitendraPancholi 如果你创建一个 List 你可以检查 id。 .Net 4 支持它。不确定早期版本。
    【解决方案2】:

    这将转换为 Linq to SQL 中的 where in 子句...

    var myInClause = new string[] {"One", "Two", "Three"};
    
    var results = from x in MyTable
                  where myInClause.Contains(x.SomeColumn)
                  select x;
    // OR
    var results = MyTable.Where(x => myInClause.Contains(x.SomeColumn));
    

    对于您的查询,您可以执行以下操作...

    var results = from states in _objectdatasource.StateList()
                  where listofcountrycodes.Contains(states.CountryCode)
                  select new State
                  {
                      StateName = states.StateName
                  };
    // OR
    var results = _objectdatasource.StateList()
                      .Where(s => listofcountrycodes.Contains(s.CountryCode))
                      .Select(s => new State { StateName = s.StateName});
    

    【讨论】:

    • 谢谢 ;) 也帮助了我 +1
    【解决方案3】:

    我喜欢它作为一种扩展方法:

    public static bool In<T>(this T source, params T[] list)
    {
        return list.Contains(source);
    }
    

    现在你打电话:

    var states = _objdatasources.StateList().Where(s => s.In(countrycodes));
    

    您也可以传递单个值:

    var states = tooManyStates.Where(s => s.In("x", "y", "z"));
    

    感觉更自然,更接近sql。

    【讨论】:

    • 我应该在哪里写这个扩展方法
    • @Rohaan,在任何静态类中(非通用类且非嵌套类)
    • 如果您要重用 linq 中的 Where In 部分,那么编写扩展类的工作就只有一步之遥了。赞成答案,但只是想让其他遇到这个问题的人直接进入扩展方法路线。
    • @Jurg 经常需要,不是吗?我用它所有的时间。 Linq to Objects 工作正常,IQueryables 没有尝试过。
    • 不是我的意思,它经常被使用,但是在一个特定的项目中,如果你只需要在一个控制器中执行此操作(也就是一次),那么就不需要扩展方法。这更适合 c#/linq 的新手 :)
    【解决方案4】:
    public List<Requirement> listInquiryLogged()
    {
        using (DataClassesDataContext dt = new DataClassesDataContext(System.Configuration.ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString))
        {
            var inq = new int[] {1683,1684,1685,1686,1687,1688,1688,1689,1690,1691,1692,1693};
            var result = from Q in dt.Requirements
                         where inq.Contains(Q.ID)
                         orderby Q.Description
                         select Q;
    
            return result.ToList<Requirement>();
        }
    }
    

    【讨论】:

    • 什么是等价方法语法?
    • 非常感谢您,为此苦苦挣扎了好几天,这是唯一有效的方法。如此简单有效的解决方案。
    【解决方案5】:

    “IN”子句通过 .Contains() 方法内置到 linq 中。

    例如,要获取所有 .States 为“NY”或“FL”的人:

    using (DataContext dc = new DataContext("connectionstring"))
    {
        List<string> states = new List<string>(){"NY", "FL"};
        List<Person> list = (from p in dc.GetTable<Person>() where states.Contains(p.State) select p).ToList();
    }
    

    【讨论】:

      【解决方案6】:
      from state in _objedatasource.StateList()
      where listofcountrycodes.Contains(state.CountryCode)
      select state
      

      【讨论】:

        【解决方案7】:

        这个有点不同的想法。但它会对你有用。我在 linq 主查询中使用了子查询。

        问题:

        假设我们有文档表。架构如下 架构:文档(名称、版本、作者、修改日期) 复合键:名称、版本

        所以我们需要获取所有文档的最新版本。

        解决方案

         var result = (from t in Context.document
                                  where ((from tt in Context.document where t.Name == tt.Name
                                        orderby tt.Version descending select new {Vesion=tt.Version}).FirstOrDefault()).Vesion.Contains(t.Version)
                                  select t).ToList();
        

        【讨论】:

          【解决方案8】:
          public List<State> GetcountryCodeStates(List<string> countryCodes)
          {
              List<State> states = new List<State>();
              states = (from a in _objdatasources.StateList.AsEnumerable()
              where countryCodes.Any(c => c.Contains(a.CountryCode))
              select a).ToList();
              return states;
          }
          

          【讨论】:

          • 欢迎您,在这里,解释为什么要使用您的解决方案而不是如何使用是一个很好的做法。这将使您的答案更有价值,并帮助进一步的读者更好地理解您是如何做到的。我还建议您查看我们的常见问题解答:stackoverflow.com/faq
          猜你喜欢
          • 2017-07-05
          • 1970-01-01
          • 1970-01-01
          • 2018-04-22
          • 1970-01-01
          • 2011-06-16
          • 1970-01-01
          • 2010-09-30
          • 1970-01-01
          相关资源
          最近更新 更多