عبارت Select

عبارت Select در LINQ با استفاده از projection داده‌ها را در نتیجه پرس و جو قرار می‌دهد. طرح ریزی (projection) فرایند تبدیل شیء به فرم جدیدی است. عبارت Select در LINQ باید در پایان کوئری نوشته شود. شما می‌توانید عملیات زیادی را بر روی مقدار پرس و جو شده انجام دهید از جمله: بدست آوردن یک خاصیت مشخص یا ساخت نوع بی نام که از خاصیت‌های شیء پرس و جو شده استفاده می‌کند. نتیجه یک پرس و جو مجموعه‌ای است که رابط IEnumerable<T> را پیاده سازی می‌کند که در آن T نوع خروجی عبارت Select است. به عنوان نمونه، اگر عبارت Select به یک شیء person از مجموعه اشیاء Person اشاره کند، مجموعه نهایی، مجموعه‌ای است که رابط IEnumerable<Person> را پیاده سازی می‌کند. اگر دستور Select تنها خصوصیت رشته‌ای FirstName از هر شخص را انتخاب کند، مجموعه نهایی رابط IEnumerable<string> را پیاده سازی می‌کند. برای نمایش نتایج یک پرس و جو می‌توانید از یک حلقه foreach استفاده کنید. همچنین شما با انتخاب متغیر موقت می‌توانید شیء پرس وجو شده را به طور کامل انتخاب کنید. این کار باعث انتخاب شیء پرس و جو شده بدون هیچ تغییری می‌شود.

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

var results = from number in numbers
              select number;

foreach (var n in results)
{
     Console.Write("{0, -2}", n);
}
1 2 3 4 5 6 7 8 9 10

شما می‌توانید انواع مختلفی از عبارت را در دستور select بنویسید. به عنوان مثال می‌توانید تک تک اعداد موجود در آرایه‌ای از اعداد را بدست آورده و سپس یک واحد به آن‌ها اضافه کنید.

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

var results = from number in numbers
              select number + 1;

foreach (var n in results)
{
     Console.Write("{0, -2}", n);
}
2 3 4 5 6 7 8 9 10 11

همچنین در طول فرایند انتخاب می‌توانید یک خصوصیت یا ترکیبی از خصوصیات را انتخاب کنید. به عنوان مثال، شما می‌توانید خصوصیت FirstName از هر شیء Person را انتخاب کنید.

List<Person> people = new List<Person> 
{
    new Person("Johnny", "Smith"),
    new Person("Mark", "Lawrence"),
    new Person("Jessica", "Fisher"),
    new Person("Danny", "Mayer"),
    new Person("Raynold", "Alfonzo")
};

var firstNames = from person in people
                 select person.FirstName;
Johnny
Mark
Jessica
Danny
Raynold

همچنین شما می‌توانید خصوصیات مختلف را با هم ترکیب کنید. به عنوان نمونه می‌توانید خصوصیات FirstName و LastName از هر شیء Person را با هم ترکیب کرده و به عنوان نام کامل فرد برگردانید.

var fullNames = from person in people
                select person.FirstName + " " + .person.LastName;
Johnny Smith
Mark Lawrence
Jessica Fisher
Danny Mayer
Raynold Alfonzo

عبارت select بالا باعث انتخاب نام فرد همراه با یک فضای خالی و سپس نام خانوادگی می‌شود.
شما می‌توانید از متدهای مختلف برای تغییر نتیجه خروجی استفاده کنید. به عنوان مثال قصد داریم نام افراد مختلف را به صورت حروف بزرگ در خروجی قرار دهیم.

var namesInCaps = from person in people
                  select person.FirstName.ToUpper();
JOHNNY
MARK
JESSICA
DANNY
RAYNOLD

همچنین می‌توان مقادیری که مستقیماً در منبع داده نیستند را انتخاب کنید. به عنوان نمونه، می‌توان لیستی از اندیس‌ها را انتخاب کرد و به وسیله آنها مقادیر موجود در آرایه دیگر را در خروجی قرار داد.

int[] indices = { 0, 1, 2, 3, 4 };
string[] words = { "Example1", "Example2", "Example3", "Example4", "Example5" };

var result = from index in indices
             select words[index];
Example1
Example2
Example3
Example4
Example5

می‌توان نوع‌های بی نامی را در طی عملیات select ساخت که شامل خصوصیات مشخصی از هر شیء هستند. به عنوان نمونه، فرض کنید یک شیء Person داریم که دارای خصوصیات LastName ،Age ،Gender و FirstName باشد و ما در طی عملیات select فقط خصوصیات FirstName و LastName آن را لازم داریم، برای حل این مشکل می‌توان یک نوع بی نام را در عبارت select ساخت که شامل این خصوصیات باشد.

var annonymous = from person in people
                 select new { person.FirstName, person.LastName };

foreach (var p in annonymous)
{
    Console.WriteLine(p.FirstName + " " + p.LastName);
}

نوع نتیجه خروجی، نوع بی نامی است که شامل خصوصیات انتخاب شده است. همچنین شما می‌توانید خصوصیات جدیدی را بر مبنای خصوصیات شیء پرس و جو شده ایجاد کنید.

var results = from person in people
              select new { FN = person.FirstName, LN = person.LastName };

foreach (var p in results)
{
    Console.WriteLine(p.FN + " " + p.LN);
}
Johnny Smith
Mark Lawrence
Jessica Fisher
Danny Mayer
Raynold Alfonzo

دستور select در عبارت پرس و جوی بالا مقدار خاصیت FirstName و LastName را به خاصیت‌های جدید با نام‌های متفاوت نسبت می‌دهد. نوع این خاصیت‌های جدید را کامپایلر با توجه به مقادیر نسبت داده شده به آنها تعیین می‌کند (type inference). نوع بی نام ایجاد شده این خاصیت‌های جدید را جذب می‌کند.

var results = from person in people
              select new { Upper = person.FirstName.ToUpper(), 
               Lower = person.FirstName.ToLower() }; 

foreach (var p in results)
{
   Console.WriteLine("Upper={0}, Lower={1}", p.Upper, p.Lower);
}
Upper=JOHNNY, Lower=johnny
Upper=MARK, Lower=mark
Upper=JESSICA, Lower=jessica
Upper=DANNY, Lower=danny
Upper=RAYNOLD, Lower=raynold

عبارت select بالا مقدار خاصیت FirstName را به حروف بزرگ تبدیل می‌کند و آن را به یک خاصیت جدید با نام Upper نسبت می‌دهد، در ادامه مقدار همین خاصیت را به حروف کوچک تبدیل می‌کند و آن را به یک خاصیت جدید به نام Lower نسبت می‌دهد. این دو خاصیت جدید در نوع بی نام ساخته شده قرار می‌گیرند. برای استفاده از این خاصیت‌های جدید از یک حلقه foreach استفاده می‌کنیم.

var results = from person in people
              select new { FullName = person.FirstName + " " + person.LastName };

foreach (var p in results)
{
   Console.WriteLine(p.FullName);
}
Johnny Smith
Mark Lawrence
Jessica Fisher
Danny Mayer
Raynold Alfonzo

عبارت select در کوئری بالا یک خاصیت جدید به نام FullName ایجاد می‌کند سپس جمع مقادیر خاصیت‌های FirstName و LastName را در آن قرار می‌دهد. نوع بی نام یک خاصیت به نام FullName دارد که به طور خودکار مقدار کامل نام افراد را در خود ذخیره می‌کند.

var results = from person in people
              select new { person.Age, FullName = person.FirstName + " " + person.LastName };

foreach (p in results)
{
    Console.WriteLine("FullName={0}, Age={1}", p.FullName, p.Age);
}
FullName=Johnny Smith, Age=22
FullName=Mark Lawrence, Age=24
FullName=Jessica Fisher, Age=19
FullName=Danny Mayer, Age=21
FullName=Raynold Alfonzo, Age=25

کوئری قبل شامل یک عبارت select است که یک نوع بی نام شامل 2 خاصیت ایجاد می‌کند که خاصیت اول سن افراد را نشان می‌دهد و خاصیت دوم ترکیبی از نام و نام خانوادگی را در خود ذخیره می‌کند.