LINQ如何获取一条记录并跳过休息c#

时间:2011-11-11 14:05:34

标签: c# linq

我试图拿一张唱片然后跳过休息。我的代码不会抛出任何错误但不提供任何输出。这是我的代码。所以请看看我的代码中有什么问题。

public sealed class Person
{
    public Person() { }
    public Person(string name,bool HQ) {
        this.Name = name;
        this.HQ = HQ;
    }

    private string _Name;
    public string Name
    {
        get { return _Name; }
        set { _Name = value; }
    }

    private bool _HQ;
    public bool HQ
    {
        get { return _HQ; }
        set { _HQ = value; }
    }
}

  protected void btn_Click(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("Name",typeof(string));
        dt.Columns.Add("HQ", typeof(bool));

        DataRow dr = null;
        dr = dt.NewRow();
        dr["Name"]="Arijit";
        dr["HQ"]=true;
        dt.Rows.Add(dr);

        dr = dt.NewRow();
        dr["Name"] = "Dibyendu";
        dr["HQ"] = false;
        dt.Rows.Add(dr);

        dr = dt.NewRow();
        dr["Name"] = "Tridip";
        dr["HQ"] = false;
        dt.Rows.Add(dr);


        List<Person> oPerson1 = (from c in dt.AsEnumerable()
            select new Person
            {
                Name = c.Field<string>("Name"),
                HQ = c.Field<bool>("HQ")
            }).Skip(1).Take(2).ToList();


        List<Person> oPerson2 = (from c in dt.AsEnumerable()
            select new Person
            {
                Name = c.Field<string>("Name"),
                HQ = c.Field<bool>("HQ")
            }).Take(1).Skip(2).ToList();

    }

7 个答案:

答案 0 :(得分:9)

如果您想拍摄第一条记录,可以拨打这些Take(1)First()FirstOrDefault()

如果你想在中间取1条记录,请拨打:Skip(n).Take(1)其中n - 是跳过的记录数

当您致电Take(n)时 - 之后无需拨打Skip,它已经选择了n条记录

答案 1 :(得分:4)

试试这段代码。

Person oPerson1 = (from c in dt.AsEnumerable()
select new Person
{
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
}).First(); //first person in a list


Person oPerson2 = (from c in dt.AsEnumerable()
select new Person
{
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
}).Skip(1).First(); //second person in a list

However this code can be rewritten to be clearer:

List<Person> persons = from c in dt.AsEnumerable()
select new Person
{
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
};

Person oPerson1 = persons[0];
Person oPerson2 = persons[1];

答案 2 :(得分:3)

我更喜欢使用IQueryable而不是List

无论如何,你可以使用Queryable.Skip跳过你需要的元素

   IQueryable<Person> oPerson2 = (from c in dt.AsEnumerable()
            select new Person
            {
                Name = c.Field<string>("Name"),
                HQ = c.Field<bool>("HQ")
            }).Skip(2).Take(1);

您还可以在Return or Skip Elements in a Sequence (LINQ to SQL)

中找到更多相关信息

答案 3 :(得分:2)

我不确定你的意思是“拿一个并跳过剩下的”,但我怀疑你对LINQ操作如何工作感到困惑。它们会根据您指定的条件返回序列,并且新序列只有您要求的序列。

例如,如果您有一个包含三个项目的List,并且您调用了Take(1),那么您将获得一个包含1个项目的IEnumerable。没有什么可以“跳过”,因为列表中只有一个元素。您的原始数据表保持不变 - LINQ序列是不可变的。

听起来你真正想做的就是:

    List<Person> oPerson2 = (from c in dt.AsEnumerable()
        select new Person
        {
            Name = c.Field<string>("Name"),
            HQ = c.Field<bool>("HQ")
        }).Take(1).ToList();

当然,这是LINQ中非常常见的操作,所以还有另一种更清晰的方法:

    Person oPerson2 = (from c in dt.AsEnumerable()
        select new Person
        {
            Name = c.Field<string>("Name"),
            HQ = c.Field<bool>("HQ")
        }).First();

答案 4 :(得分:1)

如果您只想获得一条记录,则应将First()FirstOrDefault()最终的ToList调用替换为此目的。 两个方法之间的区别是,First()如果没有任何返回(例如空集合)将抛出异常。 FirstOrDefault()将返回default(T)(例如,类为null,值类型为0)。

答案 5 :(得分:1)

打破链接然后:

List<Person> oPerson2 = (from c in dt.AsEnumerable()
  select new Person
  {
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
  }).Take(1).Skip(2).ToList();

变为:

var tmp0 = (from c in dt.AsEnumerable()
  select new Person
  {
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
  });
var tmp1 = tmp0.Take(1);
var tmp2 = tmp1.Skip(2);
List<Person> oPerson2 = tmp2.ToList();

这样可以更容易地看到错误。 tmp0是一个枚举,枚举时将返回每个可能的行。 tmp1是一个枚举,只返回tmp0中的前1行(如果没有足够的行,则返回更少)。 tmp2是一个可枚举的,它将跳过tmp1中的前两行(如果没有足够的行,则更少),然后返回其余的行。最后,oPerson2使这些枚举实际返回结果并将其存储在列表中。

由此可以清楚地看出错误是.Skip(2),因为它采用单元素枚举并跳过最多2个而剩下其余部分,从而产生一个max(1 - 2,0)= 0元素的列表

忽略Skip()并得到你想要的东西,因为“占用1”已经需要“跳过剩下的”。

答案 6 :(得分:0)

还可以使用.First()实现此目的

List<X> xlist= XBusiness.GetAllX(xname.ToString());
X lastX = xlist.First();