عبارت join – انجام یک عمل inner join
Inner joins سادهترین عمل اتصال است. این نوع اتصال یک خروجی شبیه یک جدول بر میگرداند. به این معنی اگر شما به نتیجه پرس و جو نگاه کنید شبیه به یک جدولی خواهد بود که هر سلول از آن یک مقدار دارد. فرض کنید دو جدول در پایگاه داده به نامهای Authors و Books دارید. جدول Author شامل اطلاعاتی در مورد مؤلفهای مختلف است. در جدول Books نیز اطلاعاتی در مورد کتابها همراه با شناسه مؤلف آن کتاب وجود دارد. اتصال دو جدول با استفاده از Inner joins یک خروجی شبیه شکل زیر بر میگرداند.
Author |
Book |
John Smith | Little Blue Riding Hood |
John Smith | Snow Black |
John Smith | Hanzel and Brittle |
Harry Gold | My Rubber Duckie |
Harry Gold | He Who Doesn’t Know His Name |
Ronald Schwimmer | The Three Little Piggy Banks |
هر مؤلف میتواند چندین کتاب مربوط به خود داشته باشد. همانطور که در بالا مشاهده میکنید مؤلف John Smith سه کتاب، مؤلف Harry Gold دو کتاب و Ronald Schwimmer یک کتاب تألیف کردهاند.
هر آیتم در منبع دادهی داخلی با آیتم نظیر خود در منبع دادهی خارجی ترکیب شده و سپس یک آیتم جدید را تشکیل میدهند. اولین آیتم داخلی به دنبال تمامی آیتمهای نظیر خود در منبع خارجی میگردد و با آنها ترکیب میشود و تشکیل یک آیتم جدید میدهد. برای دومین، سومین و… داخلی هم همین عمیل انجام میگیرد. برای تشخیص اینکه آیا دو آیتم با هم نظیر هستند، هر دو آیتم باید دارای یک خاصیت یا عضو باشند که از لحاظ مساوی بودن با یکدیگر مقایسه شوند. همانطور که در شکل بالایی میبینید آیتم چهارم در منبع دادهی خارجی در نتیجه پرس و جو قرار نگرفته است. هر آیتم در منبع دادهی خارجی که دارای عضو نظیر در منبع دادهی داخلی نباشد در نتیجه قرار نمیگیرد. همین عمل در رابطه با آیتمهای موجود در منبع دادهی داخلی هم صدق میکند.
به مثال زیر توجه کنید. در این مثال دو کلاس به نامهای Author و Book تعریف شدهاند.
class Author { public int AuthorId { get; set; } public string Name { get; set; } } class Book { public int AuthorId { get; set; } public string Title { get; set; } }
همانطور که در مثال بالا مشاهده میکنید هر دو کلاس دارای خاصیت مشابهی به نام AuthorId هستند. این خاصیت برای تشخیص آیتمهای نظیر در طی عملیات اتصال استفاده میشود. به این نکته توجه کنید که نام خاصیتها لازم نیست با یکدیگر مساوی باشد اما باید هر دو خاصیت دارای نوع دادهای یکسانی باشند. در کد زیر اشیایی از هر دو کلاس Author و Books ایجاد شدهاند. هر کتاب با استفاده از خاصیت AuthorId خود به یک مؤلف اشاره میکند.
1: class Program 2: { 3: public static void Main(string[] args) 4: { 5: Author[] authors = new Author[] 6: { 7: new Author() { AuthorId = 1, Name = "John Smith" }, 8: new Author() { AuthorId = 2, Name = "Harry Gold" }, 9: new Author() { AuthorId = 3, Name = "Ronald Schwimmer" }, 10: new Author() { AuthorId = 4, Name = "Jerry Mawler" } 11: }; 12: 13: Book[] books = new Book[] 14: { 15: new Book() { AuthorId = 1, Title = "Little Blue Riding Hood" }, 16: new Book() { AuthorId = 3, Title = "The Three Little Piggy Banks" }, 17: new Book() { AuthorId = 1, Title = "Snow Black" }, 18: new Book() { AuthorId = 2, Title = "My Rubber Duckie" }, 19: new Book() { AuthorId = 2, Title = "He Who Doesn't Know His Name" }, 20: new Book() { AuthorId = 1, Title = "Hanzel and Brittle" } 21: }; 22: 23: var result = from a in authors 24: join b in books on a.AuthorId equals b.AuthorId 25: select new { a.Name, b.Title }; 26: 27: foreach (var r in result) 28: { 29: Console.WriteLine("{0} - {1}", r.Name, r.Title); 30: } 31: } 32: }
John Smith - Little Blue Riding Hood John Smith - Snow Black John Smith - Hanzel and Brittle Harry Gold - My Rubber Duckie Harry Gold - He Who Doesn't Know His Name Ronald Schwimmer - The Three Little Piggy Banks
در خطوط 23-25 از یک عبارت join استفاده شده است. عبارت پرس و جو ابتدا یک شیء مؤلف را از منبع دادهی خارجی که همان Authors است میگیرد، سپس در عبارت join یک شیء کتاب را از منبع دادهی داخلی که همان Books است انتخاب میکند در نهایت مقدار خاصیت AuthorId از هر دو شیء انتخاب شده را از لحاظ یکسان بودن با هم مقایسه میکند .
به این نکته توجه کنید که از کلمه کلیدی equal به جای عملگر == استفاده شده است. عبارت join فقط از لحاظ تساوی دو شیء را مقایسه میکند. شما نمیتواند از عملگرهایی مانند > یا > برای مقایسه کلیدها استفاده کنید. بنابراین مایکروسافت برای یادآوری این نکته کلمه کلیدی equals را به وجود آورده است.
اگر خاصیت AuthoId کتاب با AuthorId مؤلف برابر باشد، میتوانید با استفاده از عبارت select نام مؤلف و عنوان کتاب را ترکیب کنید و در نتیجه پرس و جو قرار دهید. هر کتاب با تمامی مؤلفها مقایسه میشود و با آنهایی که نظیر باشد (تعلق داشته باشد) در نتیجه پرس و جو قرار میگیرد. به این نکته توجه کنید که مولفی با نام Jerry Mawler در نتیجه پرس وجو قرار نمیگیرد زیرا دارای کتابی در منبع دادهی داخلی وجود ندارد که با آن ترکیب شود. همچنین هر کتابی که آیتم نظیری نداشته باشد در نتیجه پرس وجو قرار نمیگیرد. عبارت join مانند سایر عبارات در طی عملیات کامپایل به شکل متدی خود تبدیل میشود. عبارت پرس وجوی موجود در مثال بالا را میتواند به شکل زیر نوشت :
var result = authors.Join(books, author => author.AuthorId, book => book.AuthorId, (author, book) => new { author.Name, book.Title } );
این نسخه از متد Join نقش یک inner join را بازی میکند. این متد چهار پارامتر قبول میکند. اولین پارامتر منبع داده داخلی که در اینجا Books است، میباشد. دومین پارامتر یک عبارت لامبدا که شامل همه آیتمهای منبع داده خارجی همراه با کلیدی است که هر آیتم از منبع داده خارجی بر اساس آن با آیتم نظیر خود در منبع داده داخلی ترکیب میشود (در این مثال AuthorId به عنوان کلید به کار رفته است). سومین پارامتر هم یک عبارت لامبدا که شامل همه آیتمهای منبع داده داخلی همراه با کلیدی که با کلید منبع داده خارجی مقایسه میشود، میباشد. و در نهایت چهارمین پارامتر، گه عبارت لامبدایی با دو پارامتر است، یکی آیتم خارجی و دیگری آیتم داخلی که دارای کلیدهای یکسانی هستند و نتیجه نهایی از ترکیب این دو آیتم میباشد.
با سلام خدمت استاد محترم. میشه توضیحاتی هم در مورد left inner join , right inner join و هم چنین join ها با چند شرط بدین؟ ممنون . درضمن از شما به خاطر راه اندازی سایت خوبتون تشکر میکنم .
چی بگم؟!
خدایی دمتون گرم
خیلی سایت خوبیه! حسابی داره مشکل منو حل میکنه.
اجرتون با امام زمان(عج)