我试图拿一张唱片然后跳过休息。我的代码不会抛出任何错误但不提供任何输出。这是我的代码。所以请看看我的代码中有什么问题。
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();
}
答案 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);
中找到更多相关信息
答案 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();