[英]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.