PDA

View Full Version : استفاده از group by در linq



mory123
شنبه 22 فروردین 1394, 20:06 عصر
با سلانم خدمت اساتید محترم.
تو یک پروژه دارم از قطعه کد زیر استفاده میکنم :
var query = kd.tblKGWorks.Where(p => p.FormID == 2927) .GroupBy(p => new{ p.ProcessInstanceID }).Select(g => new {g.Key.ProcessInstanceID , g.Max(s=>s.ID) });

اما error میده :
Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple
name or member access.
لطفا راهنماییم کنیین با تشکر. درضمن اگه امکانش هست توضیحی هم در مورد عبارات لامبادا برای group by , where بدین . با تشکر.

csharp.net
شنبه 22 فروردین 1394, 20:15 عصر
سلام دوست عزیز

این دو مقاله از سایت w3-farsi.com (http://www.w3-farsi.com) رو مطالعه بفرمایید شاید بتونید مشکلتونو حل کنید

عبارت where

شما می توانید نتیجه پرس و جو را با استفاده از عبارت where فیلتر کنید. بعد از کلمه کلیدی where یک شرط (یا مجموعه ای شروط) قرار می گیرد ، هر عنصری که در نتیجه پرس و جو قرار می گیرد با این شرط مطابقت دارد. نکته بسیار مهمی که اهمیت دارد این است که برای نوشتن شرط می توانید از متدهایی که در کتابخانه کلاس .Net Framework قرار دارد استفاده نمایید. این درس به شما نشان می دهد که چگونه با استفاده از عبارت where نتیجه پرس و جو را فیلتر نمایید. با استفاده از عملگر های مقایسه ای می توان مقدار یا خاصیتی از یک شی را با یک مقدار دیگر مقایسه کرد . به عنوان مثال ، قصد داریم عناصر یک آرایه عددی را که بزرگتر از 5 هستند انتخاب نماییم ، پرس و جویی که می نویسیم به شکل زیر است :


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

var greaterThanFive = from number in numbers
where number > 5
select number; در مثال بالا شرط داخل عبارت where تعیین می کند فقط مقادیری از آرایه که بزرگتر از 5 باشند در نتیجه پرس و جو قرار گیرند.
با استفاده از عملگرهای منطقی شرط های پیچیده تری را می توان نوشت :

var sixToTen = from number in numbers
where number > 5 && number <= 10
select number; کوئری بالا مقادیری که بزرگتر از 5 و کوچکتر مساوی با 10 هستند در نتیجه پرس و جو قرار می دهد. اگر مجموعه ای از اشیا با تعدادی خاصیت داشته باشید ، می توان از خاصیت های آنها برای نوشتن شرط عبارت where استفاده کنید :

List<Person> people = GetPersonList();

var smiths = from person in people
where person.LastName == "Smith"
select person; کوئری بالا اشخاصی که مقدار خاصیت LastName آنها برابر Smith هست را در نتیجه پرس و جو قرار می دهد. همانطور که گفته شد می توان از متدهای .net برای نوشتن شرط استفاده کرد ، به عنوان مثال قصد داریم تمامی اشخاصی که مقدار خاصیت lastname آنها با حرف R شروع می شود را انتخاب کنیم ، عبارت پرس وجو زیر این کار را انجام می دهد :

var startsWithR = from person in people
where person.LastName.StartsWith("R")
select person; در کوئری بالا از متد ()StartsWith کلاس String استفاده شده است ، این متد در صورتی که رشته با آرگومان ارسالی به این متد شروع شود true را بر می گرداند. متناوبا ، می توان از متد توسعه یافته ()Where از فضای نامی System.Linq برای نوشتن شرط استفاده کرد. این متد یک پارامتر از نوع عبارات لامبدا می پذیرد ، این عبارت لامبدا یک پارامتر دارد که عنصر پرس و جو شده در آن قرار می گیرد و بدنه آن شامل یک شرط است. خروجی این متد مجموعه ای از اشیا است .

var greaterThanFive = numbers.Where ( number => number > 5 ); در بدنه عبارت لامبدا یک دستور شرطی ساده قرار دارد که بررسی می کند که آیا مقدار عدد بزرگتر از 5 است یا نه . در زیر مثالی دیگر را مشاهده می نمایید که اشخاصی که خصوصیت LastName آنها با حرف R شروع می شود را در نتیجه پرس و جو قرار می دهد.

var startsWithR = people.Where( person => person.LastName.StartsWith("R") ); می توان از یکی از سربارگذاری های این متد که یک عبارت لامبدا با 2 پارامتر را قبول می کند نیز استفاده کنید . اولین پارامتر نماینده ی هر یکی از اشیا مجموعه می باشد ، و پارامتر دوم اندیس آن شی در مجموعه را تعیین می کند. مثال زیر اشیایی از مجموعه را بر می گرداند که اندیس آنها در مجموعه زوج باشد .

var evenIndices = numbers.Where( (number, index) => index % 2 == 0 ); از متد ()Where می توان زمانی استفاده کرد که بخواهید یکی مجموعه را بر اساس یک شرط مشخص فیلتر کنید .





عبارت group by

عبارت group by با استفاده از مقدار یک کلید، آیتم ها را گروه بندی می کند. این عبارت می تواند بین عبارت from و select یا در آخر عبارت پرس و جو قرار گیرد. ساختار ابتدایی یک عبارت group by به شکل زیر است :

group item by key into groupVar عبارت group-by با کلمه کلیدی group و نام آیتمی که قصد گروه بندی آن را داریم شروع می شود. سپس بعد از آن، کلمه کلیدی by را که کلید گروه بندی را مشخص می کند می نویسیم. به عنوان مثال کلید گروه بندی می تواند نام شهر باشد تا تمامی آیتم هایی که دارای شهر یکسانی هستند در یک گروه قرار گیرند. و در آخر کلمه کلیدی into با نام گروهی جدیدی که آیتم در آن قرار می گیرد(groupVar) نوشته می شود. groupVar دارای نوع System.Linq.IGrouping<TKey, TElement> می باشد که مشخص می کند که کلید گروه از نوع TKey و آیتم های گروه از نوع TElement است. به عنوان مثال ، فرض کنید شما می خواهید تعدادی بازیکن را در تیم های مختلف قرار دهید. در زیر کلاسی با نام Player (خطوط 10-6) با دو خاصیت Name و Team تعریف شده است.

1: using System;
2: using System.Collections.Generic;
3: using System.IO;
4: using System.Linq;
5:
6: public class Player
7: {
8: public string Name { get; set; }
9: public string Team { get; set; }
10: }
11:
12: public class Program
13: {
14: public static void Main()
15: {
16: List<Player> players = new List<Player>
17: {
18: new Player { Name = "Johnny", Team= "Red Team" },
19: new Player { Name = "Ross", Team = "Blue Team" },
20: new Player { Name = "Eric", Team = "Black Team" },
21: new Player { Name = "Josh", Team = "White Team" },
22: new Player { Name = "Mandy", Team = "Blue Team" },
23: new Player { Name = "Flora", Team = "White Team" },
24: new Player { Name = "Garry", Team = "Red Team" },
25: new Player { Name = "Joseph", Team = "Blue Team"},
26: new Player { Name = "Murray", Team = "Black Team"},
27: new Player { Name = "Henry", Team = "Black Team"},
28: new Player { Name = "Watson", Team = "Red Team"},
29: new Player { Name = "Linda", Team = "White Team"}
30: };
31:
32: var groups = from p in players
33: group p by p.Team into g
34: select new { GroupName = g.Key, Members = g };
35:
36: foreach (var g in groups)
37: {
38: Console.WriteLine("Members of {0}", g.GroupName);
39:
40: foreach (var member in g.Members)
41: {
42: Console.WriteLine("---{0}", member.Name);
43: }
44: }
45: }
46: } Members of Red Team
---Johnny
---Garry
---Watson
Members of Blue Team
---Ross
---Mandy
---Joseph
Members of Black Team
---Eric
---Murray
---Henry
Members of White Team
---Josh
---Flora
---Linda در خطوط 30-16 لیستی از بازیکن ها را ایجاد می کنیم. قصد داریم که بازیکن ها را بر اساس نام تیم گروه بندی کنیم، به صورتی که بازیکن های تیم های مشابه در یک گروه قرار گیرند. عبارت پرس و جو در خطوط 34-32 از بک عبارت group by برای گروه بندی استفاده کرده است. بازیکن های با مقدار خاصیت Team مشابه در یک گروه که رابط IGrouping<string, Player> را پیاده سازی می کند قرار می گیرند.
از آنجاییکه ما از تیم که از نوع رشته است به عنوان کلید استفاده کرده ایم خاصیت Key هم از نوع رشته خواهد بود. سپس در عبارت select (خط 34) یک نوع بی نام با دو خاصیت GroupName و Members را ساخته و به ترتیب مقدار کلید و اعضای گروه را به آنها نسبت می دهیم. خطوط 44-36 با استفاده از حلقه foreach پرس و جو را اجرا می کند
برای چاپ مقادیر نیاز به دو حلقه foreach داریم.حلقه اول برای چرخش در بین گروه های مختلف و چاپ نام آنها و حلقه دوم برای چاپ اعضای گروه ها. برای چاپ نام از مقدار خاصیت GroupName و برای چاپ اعضای گروه از خاصیت Members استفاده می کنیم.

خاتمه یک عبارت پرس و جو با استفاده از عبارت group by

عبارت group by می تواند در انتهای عبارت پرس و جو نیز قرار گیرد. به خاطر داشته باشید که یک عبارت پرس و جو می تواند با یک عبارت select یا group by خاتمه پیدا کند.در زیر مثالی را مشاهده می کنید که در آن عبارت پرس وجو با یک عبارت group by خاتمه پیدا می کند.

var groups = from p in players
group p by p.Team;

foreach (var g in groups)
{
Console.WriteLine("Members of {0}", g.Key);

foreach (var member in g)
{
Console.WriteLine("---{0}", member.Name);
}
} عبارت پرس وجو بالا نتیجه ای مشابه مثال قبلی تولید می کند. نوع نتیجه کوئری IEnumerable<IGrouping<string, Player>> است ، به این معنی که شامل مجموعه ای از گروه ها با کلیدی از نوع رشته و اشیاء Player می باشد. در داخل اولین حلقه foreach ، ابتدا با استفاده از مقدار Key هر گروه نام گروه را در خروجی می نویسیم . حلقه داخلی برای چاپ اعضای گروه از نام متغیر گروه به عنوان منبع داده استفاده می کند.نکته قابل توجه این است که هر متغیر موقت قبل از عبارت group by بعد از آن قابل دسترسی نیست.

متد GroupBy()

هر عبارت group-by به یک فراخوانی متد GroupBy() تبدیل می شود که یک متد توسعه یافته از رابط IEnumerable<T> است. مثال زیر به شما نشان می دهد که چگونه عبارت پرس وجو بالا را با استفاده از شکل متدی بنویسید :

var groups = players.GroupBy(p => p.Team); متد GroupBy() یک عبارت لامبدا که دارای یک پارامتر و یک خروجی است را به عنوان پارامتر قبول می کند . پارامتر و خروجی عبارت لامبدا به ترتیب بیانگر یک عضو گروه و کلید گروه بندی می باشند. عبارت پرس و جو مثال قبلی را می توانید به شکل زیر نیز بنویسید :

var groups = players.GroupBy(p => p.Team)
.Select(g => new { GroupName = g.Key, Members = g });

mory123
شنبه 22 فروردین 1394, 20:33 عصر
دوست عزیز جواب داد . واقعا از شما متشکرم.