[h=4]مقدمه این مقاله، مقدمه ایست بر استفاده از queryهای LINQ to Objects جهت ساپورت یک برنامه windows forms. این مقاله، ساختار عبارات LINQ to Objects را مورد بحث قرار می دهد و توضیح می دهد چگونه می توان از LINQ to Objects بدون بافت (context) یک برنامه واقعی استفاده کرد.
پروژه ای که در این مقاله آورده شده است، یک contact manager ساده است که ممکن است برای capture کردن و ذخیره اطلاعات مخاطب های یک شخص در قالب دفتر تلفن، مورد استفاده قرار گیرد. این برنامه از LINQ to Objects برای مدیریت، query کردن و مرتب کردن لیست مخاطبین، استفاده می کند. همچنین این برنامه شامل یک فایل contact مبتدی با مجموعه ای از مخاطبین تستی است.
این برنامه دارای عملکردهای ریز است:
[h=4]عبارات LINQ to Objects این بخش، بعضی از تکنیک های رایج و مورد استفاده در ساختار عبارات LINQ to Objects را مورد بحث قرار می دهد. به طور خلاصه، LINQ to Objects، ابزاری برای مدیریت queryهایی در collectionهای درون حافظه در اختیار برنامه نویسان قرار می دهد. این تکنیک ها که برای query کردن چنین collectionهایی استفاده می شوند، شبیه روش هایی هستند که برای مدیریت queryها در databaseهای رابطه ای استفاده می شوند، ولی ساده تر هستند.
[h=5]آناتومی عبارات LINQ to Objects مثال 1: یک Select ساده
این، مثالی بسیار ساده از عبارات LINQ to Objects است:
string[] tools = { "Tablesaw", "Bandsaw", "Planer", "Jointer", "Drill",
"Sander" };
var list = from t in tools
select t;
StringBuilder sb = new StringBuilder();
foreach (string s in list)
{
sb.Append(s + Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Tools");
در این مثال، آرایه ای از رشته ها (ابزارها) به صورت collectionهایی از اشیا استفاده شده تا با استفاده از LINQ to Objects، کوئری شوند.
کوئری LINQ to Objects:
var list = from t in tools
select t;
در این مثال، یک متغیر بی نوع (untyped variable) به نام "list" ایجاد می شود و همه آیتم های موجود در string array به این این object اضافه می شوند، این typeها هر کدام دارای معنای خاصی است، مثلاً "t" بمعنای tools است؛ از آنجاییکه "tools" یک string array است، framework استنباط می کند که "t" یک string نیز هست. البته، این موضوع آنقدرها هم افتضاح نیست، زیرا شما می توانید array را تکرار کنید تا لزوماً همان کار را انجام دهید؛ اما می توانید queryهای پیچیده تری را با LINQ to Objects ایجاد کنید.
مثال 2: Select با یک Where Clause
این مثال، یک کوئری LINQ to Objects را نشان می دهد که شامل یک where clause می شود. در این مثال، با مجموعه ای پرنده ها به شکل یک string array شروع می کنیم؛ از LINQ to Objects برای query کردن این string array استفاده می شود تا یک subset از array را به شکل همه پرندگانی که با حرف R شروع می شوند پیدا کند و بازگرداند.
string[] Birds = { "Indigo Bunting", "Rose Breasted Grosbeak", "Robin",
"House Finch", "Gold Finch", "Ruby Throated
Hummingbird","Rufous Hummingbird", "Downy Woodpecker"
};
var list = from b in Birds
where b.StartsWith("R")
select b;
StringBuilder sb = new StringBuilder();
foreach (string s in list)
{
sb.Append(s + Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "R Birds");
اگر قرار بود این query را اجرا کنیم، (همه پرندگانی که با R شروع می شوند، نشان داده شده اند)
مثال 3: Select با یک Where Clause
این کوئری، با اندک تفاوتی نسبت به مثال قبلی، بدنبال یک جفت دقیق در کلمه where است:
string[] Birds = { "Indigo Bunting", "Rose Breasted Grosbeak", "Robin",
"House Finch", "Gold Finch", "Ruby Throated
Hummingbird","Rufous Hummingbird", "Downy Woodpecker"
};
var list = from b in Birds
where b == "House Finch"
select b;
StringBuilder sb = new StringBuilder();
foreach (string s in list)
{
sb.Append(s + Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Found Bird");
مثال 4: generate کردن یک Ordered List
در این کوئری، لیستی از پرندگان به ترتیب حروف الفبا مرتب شده است:
string[] Birds = { "Indigo Bunting", "Rose Breasted Grosbeak", "Robin",
"House Finch", "Gold Finch", "Ruby Throated
Hummingbird","Rufous Hummingbird", "Downy Woodpecker"
};
var list = from b in Birds
orderby b ascending
select b;
StringBuilder sb = new StringBuilder();
foreach (string s in list)
{
sb.Append(s + Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Alphabetized Birds");
مثال 5: کار کردن با یک type سفارشی
در این مثال، یک ایست type شده ایجاد می شود و سپس با استفاده از LINQ to Objects، کوئری می شود.
List<Parts> parts = new List<Parts>();
Parts p1 = new Parts();
p1.PartNumber = 1;
p1.PartDescription = "Cog";
parts.Add(p1);
Parts p2 = new Parts();
p2.PartNumber = 2;
p2.PartDescription = "Widget";
parts.Add(p2);
Parts p3 = new Parts();
p3.PartNumber = 3;
p3.PartDescription = "Gear";
parts.Add(p3);
Parts p4 = new Parts();
p4.PartNumber = 4;
p4.PartDescription = "Tank";
parts.Add(p4);
Parts p5 = new Parts();
p5.PartNumber = 5;
p5.PartDescription = "Piston";
parts.Add(p5);
Parts p6 = new Parts();
p6.PartNumber = 6;
p6.PartDescription = "Shaft";
parts.Add(p6);
Parts p7 = new Parts();
p7.PartNumber = 7;
p7.PartDescription = "Pulley";
parts.Add(p7);
Parts p8 = new Parts();
p8.PartNumber = 8;
p8.PartDescription = "Sprocket";
parts.Add(p8);
var list = from p in parts
orderby p.PartNumber ascending
select p;
StringBuilder sb = new StringBuilder();
foreach (Parts p in parts)
{
sb.Append(p.PartNumber + ": " + p.PartDescription +
Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Parts List");
هدف از این مثال، تنها sort کردن لیست بخش ها به ترتیب شماره بخش ها می باشد.
کلاس parts استفاده شده در این type پشت لیست parts به شرح زیر است:
public class Parts
{
private int mPartNumber;
private string mPartDescription;
public Parts()
{
}
public Parts(int partNum, string partDescr)
{
mPartNumber = partNum;
mPartDescription = partDescr;
}
public int PartNumber
{
get { return mPartNumber; }
set { mPartNumber = value; }
}
public string PartDescription
{
get { return mPartDescription; }
set { mPartDescription = value; }
}
}
مثال 6: جستجوی یک List<T> با استفاده از LINQ to Objects
در این مثال، یک لیست type شده ایجاد و populate می شود، و سپس با استفاده از LINQ to Objects کوئری می شود. در این مورد، کوئری شامل کلمه "where" است که فقط matchهایی را بازمیگرداند که با حرف "S" شروع می شوند"
// only return parts starting with 'S'
var matchingParts = from m in parts
where m.PartDescription.StartsWith("S")
select m;
StringBuilder sb = new StringBuilder();
foreach (Parts p in matchingParts)
{
sb.Append(p.PartNumber + ": " + p.PartDescription +
Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Matching Parts List");
مثال 7: جستجوی یک List<T> با استفاده از LINQ to Objects و بازگرداندن یک Single Result
در این مثال، یک لیست type شده ایجاد و populate می شود، و سپس با استفاده از LINQ to Objects کوئری می شود. در این مورد، یک single result از تایپ “Parts” را بازمی گرداند:
var matchingPart = (from m in parts
where m.PartNumber.Equals(5)
select m).Single<Parts>();
MessageBox.Show(matchingPart.PartDescription, "Matching Part");
ممکن است کسی از روش زیر نیز برای بازگرداندن یک single value از query استفاده کند:
var matchingPart = (from m in parts
where m.PartNumber.Equals(5)
select m.PartDescription).Single<String>();
MessageBox.Show(matchingPart, "Matching Part");
هر دو روش یک نتیجه را می دهند،
هدف از مثال های بالا، مروری ساده بر چگونگی مدیریت queryهای پایه ای در collectionها با استفاده از LINQ to Objects بود؛ مسلماً عملیات های پیچیده تری نیز وجود دارند که می توان با استفاده از فرآیندهای مشابه اجرا کرد.
پروژه ای که در این مقاله آورده شده است، یک contact manager ساده است که ممکن است برای capture کردن و ذخیره اطلاعات مخاطب های یک شخص در قالب دفتر تلفن، مورد استفاده قرار گیرد. این برنامه از LINQ to Objects برای مدیریت، query کردن و مرتب کردن لیست مخاطبین، استفاده می کند. همچنین این برنامه شامل یک فایل contact مبتدی با مجموعه ای از مخاطبین تستی است.
این برنامه دارای عملکردهای ریز است:
- یک فایل اطلاعات مخاطبین ایجاد می کند.
- مخاطبین را به فایل اطلاعات مخاطبین اضافه می کند.
- مخاطبین را از فایل اطلاعات مخاطبین حذف می کند.
- مخاطبین را بر اساس نام خانوادگی شان جستجو می کند.
- جزییات مخاطبین را ایجاد و ویرایش می کند.
- نام
- نام خانوادگی
- خیابان
- شهر
- ایالت
- کد پستی
- تلفن منزل
- تلفن محل کار
- تلفن همراه
- آدرس ای میل
- فایل اطلاعات مخاطبین را ذخیره می کند.
- فایل اطلاعات مخاطبین را دوباره باز می کند.
- همه مخاطبین را در فایل اطلاعات مخاطبین پیمایش می کند.
- می توان لیستی از همه مخاطبین را در فایل اطلاعات مخاطبین مشاهده کرد.
- امکان جستجو را بر اساس حرف آغازین نام خانوادگی فراهم می کند (Rolodex).
[h=4]عبارات LINQ to Objects این بخش، بعضی از تکنیک های رایج و مورد استفاده در ساختار عبارات LINQ to Objects را مورد بحث قرار می دهد. به طور خلاصه، LINQ to Objects، ابزاری برای مدیریت queryهایی در collectionهای درون حافظه در اختیار برنامه نویسان قرار می دهد. این تکنیک ها که برای query کردن چنین collectionهایی استفاده می شوند، شبیه روش هایی هستند که برای مدیریت queryها در databaseهای رابطه ای استفاده می شوند، ولی ساده تر هستند.
[h=5]آناتومی عبارات LINQ to Objects مثال 1: یک Select ساده
این، مثالی بسیار ساده از عبارات LINQ to Objects است:
string[] tools = { "Tablesaw", "Bandsaw", "Planer", "Jointer", "Drill",
"Sander" };
var list = from t in tools
select t;
StringBuilder sb = new StringBuilder();
foreach (string s in list)
{
sb.Append(s + Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Tools");
در این مثال، آرایه ای از رشته ها (ابزارها) به صورت collectionهایی از اشیا استفاده شده تا با استفاده از LINQ to Objects، کوئری شوند.
کوئری LINQ to Objects:
var list = from t in tools
select t;
در این مثال، یک متغیر بی نوع (untyped variable) به نام "list" ایجاد می شود و همه آیتم های موجود در string array به این این object اضافه می شوند، این typeها هر کدام دارای معنای خاصی است، مثلاً "t" بمعنای tools است؛ از آنجاییکه "tools" یک string array است، framework استنباط می کند که "t" یک string نیز هست. البته، این موضوع آنقدرها هم افتضاح نیست، زیرا شما می توانید array را تکرار کنید تا لزوماً همان کار را انجام دهید؛ اما می توانید queryهای پیچیده تری را با LINQ to Objects ایجاد کنید.
مثال 2: Select با یک Where Clause
این مثال، یک کوئری LINQ to Objects را نشان می دهد که شامل یک where clause می شود. در این مثال، با مجموعه ای پرنده ها به شکل یک string array شروع می کنیم؛ از LINQ to Objects برای query کردن این string array استفاده می شود تا یک subset از array را به شکل همه پرندگانی که با حرف R شروع می شوند پیدا کند و بازگرداند.
string[] Birds = { "Indigo Bunting", "Rose Breasted Grosbeak", "Robin",
"House Finch", "Gold Finch", "Ruby Throated
Hummingbird","Rufous Hummingbird", "Downy Woodpecker"
};
var list = from b in Birds
where b.StartsWith("R")
select b;
StringBuilder sb = new StringBuilder();
foreach (string s in list)
{
sb.Append(s + Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "R Birds");
اگر قرار بود این query را اجرا کنیم، (همه پرندگانی که با R شروع می شوند، نشان داده شده اند)
مثال 3: Select با یک Where Clause
این کوئری، با اندک تفاوتی نسبت به مثال قبلی، بدنبال یک جفت دقیق در کلمه where است:
string[] Birds = { "Indigo Bunting", "Rose Breasted Grosbeak", "Robin",
"House Finch", "Gold Finch", "Ruby Throated
Hummingbird","Rufous Hummingbird", "Downy Woodpecker"
};
var list = from b in Birds
where b == "House Finch"
select b;
StringBuilder sb = new StringBuilder();
foreach (string s in list)
{
sb.Append(s + Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Found Bird");
مثال 4: generate کردن یک Ordered List
در این کوئری، لیستی از پرندگان به ترتیب حروف الفبا مرتب شده است:
string[] Birds = { "Indigo Bunting", "Rose Breasted Grosbeak", "Robin",
"House Finch", "Gold Finch", "Ruby Throated
Hummingbird","Rufous Hummingbird", "Downy Woodpecker"
};
var list = from b in Birds
orderby b ascending
select b;
StringBuilder sb = new StringBuilder();
foreach (string s in list)
{
sb.Append(s + Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Alphabetized Birds");
مثال 5: کار کردن با یک type سفارشی
در این مثال، یک ایست type شده ایجاد می شود و سپس با استفاده از LINQ to Objects، کوئری می شود.
List<Parts> parts = new List<Parts>();
Parts p1 = new Parts();
p1.PartNumber = 1;
p1.PartDescription = "Cog";
parts.Add(p1);
Parts p2 = new Parts();
p2.PartNumber = 2;
p2.PartDescription = "Widget";
parts.Add(p2);
Parts p3 = new Parts();
p3.PartNumber = 3;
p3.PartDescription = "Gear";
parts.Add(p3);
Parts p4 = new Parts();
p4.PartNumber = 4;
p4.PartDescription = "Tank";
parts.Add(p4);
Parts p5 = new Parts();
p5.PartNumber = 5;
p5.PartDescription = "Piston";
parts.Add(p5);
Parts p6 = new Parts();
p6.PartNumber = 6;
p6.PartDescription = "Shaft";
parts.Add(p6);
Parts p7 = new Parts();
p7.PartNumber = 7;
p7.PartDescription = "Pulley";
parts.Add(p7);
Parts p8 = new Parts();
p8.PartNumber = 8;
p8.PartDescription = "Sprocket";
parts.Add(p8);
var list = from p in parts
orderby p.PartNumber ascending
select p;
StringBuilder sb = new StringBuilder();
foreach (Parts p in parts)
{
sb.Append(p.PartNumber + ": " + p.PartDescription +
Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Parts List");
هدف از این مثال، تنها sort کردن لیست بخش ها به ترتیب شماره بخش ها می باشد.
کلاس parts استفاده شده در این type پشت لیست parts به شرح زیر است:
public class Parts
{
private int mPartNumber;
private string mPartDescription;
public Parts()
{
}
public Parts(int partNum, string partDescr)
{
mPartNumber = partNum;
mPartDescription = partDescr;
}
public int PartNumber
{
get { return mPartNumber; }
set { mPartNumber = value; }
}
public string PartDescription
{
get { return mPartDescription; }
set { mPartDescription = value; }
}
}
مثال 6: جستجوی یک List<T> با استفاده از LINQ to Objects
در این مثال، یک لیست type شده ایجاد و populate می شود، و سپس با استفاده از LINQ to Objects کوئری می شود. در این مورد، کوئری شامل کلمه "where" است که فقط matchهایی را بازمیگرداند که با حرف "S" شروع می شوند"
// only return parts starting with 'S'
var matchingParts = from m in parts
where m.PartDescription.StartsWith("S")
select m;
StringBuilder sb = new StringBuilder();
foreach (Parts p in matchingParts)
{
sb.Append(p.PartNumber + ": " + p.PartDescription +
Environment.NewLine);
}
MessageBox.Show(sb.ToString(), "Matching Parts List");
مثال 7: جستجوی یک List<T> با استفاده از LINQ to Objects و بازگرداندن یک Single Result
در این مثال، یک لیست type شده ایجاد و populate می شود، و سپس با استفاده از LINQ to Objects کوئری می شود. در این مورد، یک single result از تایپ “Parts” را بازمی گرداند:
var matchingPart = (from m in parts
where m.PartNumber.Equals(5)
select m).Single<Parts>();
MessageBox.Show(matchingPart.PartDescription, "Matching Part");
ممکن است کسی از روش زیر نیز برای بازگرداندن یک single value از query استفاده کند:
var matchingPart = (from m in parts
where m.PartNumber.Equals(5)
select m.PartDescription).Single<String>();
MessageBox.Show(matchingPart, "Matching Part");
هر دو روش یک نتیجه را می دهند،
هدف از مثال های بالا، مروری ساده بر چگونگی مدیریت queryهای پایه ای در collectionها با استفاده از LINQ to Objects بود؛ مسلماً عملیات های پیچیده تری نیز وجود دارند که می توان با استفاده از فرآیندهای مشابه اجرا کرد.