繁体   English   中英

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

[英]LINQ How to take one record and skip rest c#

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

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

    }

如果你想获得第一条记录你可以称之为Take(1)First()FirstOrDefault()

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

当你调用Take(n) - 之后不需要调用Skip时,它已经选择了n个记录

试试这个代码。

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

我更喜欢使用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);

您还可以在序列返回或跳过元素中找到更多相关信息(LINQ to SQL)

我不确定你的意思是“拿一个并跳过其余部分”,但我怀疑你对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();

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

打破链接然后:

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”已经需要“跳过剩下的”。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM