常用LINQ关键字用法汇总
背景
傳統(tǒng)上,針對數(shù)據(jù)的查詢都以簡單的字符串表示,而沒有編譯時類型檢查或 IntelliSense 支持。此外,還需要針對每種數(shù)據(jù)源學(xué)習(xí)一種不同的查詢語言:SQL 數(shù)據(jù)庫、XML 文檔、各種 Web 服務(wù)等等。?LINQ 使查詢成為 C# 中的一流語言構(gòu)造。?可以使用語言關(guān)鍵字和熟悉的運算符針對強類型化對象集合編寫查詢。
注意事項
版本需求:.NET Framework 3.5 或更高版本
查詢對象:SQL Server 數(shù)據(jù)庫、XML 文檔、ADO.NET 數(shù)據(jù)集以及支持?IEnumerable?或泛型?IEnumerable<T>?接口的任何對象集合
引用包:System.Linq
以下按照使用度排序介紹。
Where
用于過濾數(shù)據(jù),減少IF分支語句。
例子:
StringBuilder str = new StringBuilder();
foreach (int item in list.Where(d => d % 2 == 0))
{
? ? str.Append(item);
}
老式IF用法:
StringBuilder str = new StringBuilder();
foreach (int item in list)
{
? ? if (item % 2 == 0)
? ? {
? ? ? ?str.Append(item);
? ? }
}
?
?
Take
從數(shù)據(jù)源開始位置讀取指定的元素個數(shù)用。
例子:
var list = Enumerable.Range(1, 100000);
foreach (int item in list.Take(10))
{
? ?Console.WriteLine(item.ToString());
}
Select
抽取數(shù)據(jù)源中類型的指定元素組建成新的類型。主要用于簡化數(shù)據(jù)列或者轉(zhuǎn)換數(shù)據(jù)類型,以及獲取元素Index。
例子:
var list = new List<Animal> {
? new Animal{ Name="hot dog",Sex=1,Age=10},
? new Animal{ Name="big dog",Sex=0,Age=11},
? new Animal{ Name="bin dog",Sex=0,Age=12},
? new Animal{ Name="baby dog",Sex=1,Age=13},
};
foreach (string item in list.Select(a => a.Name))
{
? Console.WriteLine(item.ToString());
}
foreach (var item in list.Select(a => new { Name = a.Name, Length = a.Age * 2, Type = "S" }))
{
? Console.WriteLine(item.ToString());
}
foreach (var item in list.Select((value, index) => new { Number = index, Name = value }))
{
? Console.WriteLine(item.ToString());
}
foreach (string item in list.Select(a => a.Sex.ToString("D2")))
{
? Console.WriteLine(item.ToString());
}
foreach (int item in list.Select(a => a.Age * 2))
{
? Console.WriteLine(item.ToString());
}
結(jié)果:
?
SelectMany
將數(shù)據(jù)源降維抽取,減少For循環(huán)。類似Select,適合多重子集的數(shù)據(jù)源抽取數(shù)據(jù)。
例子:
var parameters = new Parameter[]
{
? new Parameter() { Name = "正一", Numbers = new int[] { 1, 2, 3 } },
? new Parameter() { Name = "清次", Numbers = new int[] { 1, 3, 5 } },
? new Parameter() { Name = "誠三", Numbers = new int[] { 2, 4, 6 } },
? new Parameter() { Name = "征史", Numbers = new int[] { 9, 8, 7 } },
};
StringBuilder str = new StringBuilder();
var result = parameters.SelectMany(value => value.Numbers);
foreach (int value in result)
{
? str.Append($"{value},");
}
Console.WriteLine(str.ToString());
結(jié)果:
?
如果使用Select就是如下寫法:
var parameters = new Parameter[]
{
? new Parameter() { Name = "正一", Numbers = new int[] { 1, 2, 3 } },
? new Parameter() { Name = "清次", Numbers = new int[] { 1, 3, 5 } },
? new Parameter() { Name = "誠三", Numbers = new int[] { 2, 4, 6 } },
? new Parameter() { Name = "征史", Numbers = new int[] { 9, 8, 7 } },
};
var results = parameters.Select(value => value.Numbers);
StringBuilder str = new StringBuilder();
foreach (int[] values in results)
{
? foreach (int number in values)
? {
? ? ?str.Append($"{number},");
? }
}
Console.WriteLine(str.ToString());
結(jié)果:
?
Distinct
去掉重復(fù)數(shù)據(jù)留下一個,一般用于基礎(chǔ)數(shù)據(jù)類型。如果是類需要指定比較方法。
int[] dataA = new int[] { 0, 1, 3, 3, 2 };
List<float> dataB = new List<float>() { 1.5f, 1.5f, 1.5f, 1.5f };
IEnumerable<int> dataA_D = dataA.Distinct();
IEnumerable<float> dataB_D = dataB.Distinct();
foreach (var d in dataA_D)
{
? Console.WriteLine(d);
}
foreach (var d in dataB_D)
{
? Console.WriteLine(d);
}
?
?
Any
用來判斷列表是否為空,速度比Count()快。如果是類,可以指定判斷條件。
int[] numbersA = new int[] { };
int[] numbersB = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var list = new List<Animal> {
? new Animal{ Name="hot dog",Sex=1},
? new Animal{ Name=null,Sex=0},
? new Animal{ Name="bin dog",Sex=0},
? new Animal{ Name="baby dog",Sex=1},
};
Console.WriteLine(numbersA.Any());
Console.WriteLine(numbersB.Any());
Console.WriteLine(list.Any(a => a.Name == null));
?
?
Join
兩組數(shù)據(jù)結(jié)合。也可以用來根據(jù)某個表排序數(shù)據(jù)。
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>( this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector );
參數(shù)說明:
outer:結(jié)合的數(shù)據(jù)列表A
inner:結(jié)合的數(shù)據(jù)列表B
outerKeySelector:列表A的主鍵字段
innerKeySelector:列表B的主鍵字段
resultSelector:返回結(jié)果定義。(匿名類居多)
PersonData[] persons = new PersonData[]
{
? new PersonData() { Name = "正一郎", ItemID = 0 },
? new PersonData() { Name = "清次郎", ItemID = 1 },
? new PersonData() { Name = "誠三郎", ItemID = 2 },
? new PersonData() { Name = "征史郎", ItemID = 0 },
};
ItemData[] items = new ItemData[]
{
? new ItemData() { ID = 0, Name = "金" },
? new ItemData() { ID = 1, Name = "権力" },
};
var joinList = persons.Join(
? items,
? person => person.ItemID,
? item => item.ID,
? (person, item) => new { PersonName = person.Name, ItemName = item.Name }); foreach (var item in joinList)
{
? Console.WriteLine($"Person:{item.PersonName}, Item:{item.ItemName}");
}
?
?
Except
求兩個數(shù)據(jù)列表的差分集合用。
int[] numbersA = new int[] { 1, 2, 3, 4, 5 };
int[] numbersB = new int[] { 8, 6, 4, 2, 0 };
IEnumerable<int> results = numbersA.Except(numbersB);
foreach (var d in results)
{
? Console.WriteLine(d);
}
?
?
自定義比較條件的情況
class Parameter
{
? public int ID { get; set; }
? public string Name { get; set; }
? public override string ToString()
? {
? ? return string.Format("ID:{0}, Name:{1}", ID, Name);
? }
}
class ParameterComparer : IEqualityComparer<Parameter>
{
? public bool Equals(Parameter i_lhs, Parameter i_rhs)
? {
? ? if (i_lhs.ID == i_rhs.ID &&?i_lhs.Name == i_rhs.Name)
? ?{
? ? ? ?return true;
? ? }
? ? return false;
? ?}
? ?public int GetHashCode(Parameter i_obj)
? {
? ? ?return i_obj.ID ^ i_obj.Name.GetHashCode();
? ?}
?}
class Program
{
? ?static void Main(string[] args)
? {
? ? ?Parameter[] dataA = new Parameter[]
? ? {
? ? ? ?new Parameter() { ID = 0, Name = "正一郎" },
? ? ? ?new Parameter() { ID = 5, Name = "清次郎" },
? ? ? ?new Parameter() { ID = 3, Name = "誠三郎" },
? ? ? ?new Parameter() { ID = 9, Name = "征史郎" },
? ?};
? ?Parameter[] dataB = new Parameter[]
? {
? ? ?new Parameter() { ID = 5, Name = "清次郎" },
? ? ?new Parameter() { ID = 3, Name = "誠三郎" },
? ? ?new Parameter() { ID = 2, Name = "征史郎" },
? ?};
? ParameterComparer compare = new ParameterComparer();
? IEnumerable<Parameter> results = dataA.Except(dataB, compare);
? foreach (var item in results)
? {
? ? ?Console.WriteLine(item.ToString());
? }
? Console.ReadKey();
?}}
?
?
Range
指定開始位置,指定個數(shù)的連續(xù)列表做成。
IEnumerable<int> intSequenceA = Enumerable.Range(1, 5);
IEnumerable<int> intSequenceB = Enumerable.Range(-1, 3);
IEnumerable<int> intSequenceC = Enumerable.Range(100, 4);
foreach (var d in intSequenceA)
{
? Console.WriteLine(d);
}
Console.WriteLine("=========");
foreach (var d in intSequenceB)
{
? Console.WriteLine(d);
}
Console.WriteLine("=========");
foreach (var d in intSequenceC)
{
? Console.WriteLine(d);
}
?
備注:https://www.urablog.xyz/entry/2018/07/10/070000
每天成就一小步,積累下來就是一大步。 轉(zhuǎn)發(fā)本文請注明出處,謝謝您的閱讀與分享!
?
業(yè)余時間賺點零花錢點這里
總結(jié)
以上是生活随笔為你收集整理的常用LINQ关键字用法汇总的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS中盒模型的理解
- 下一篇: 怎样才算高并发?