مرتب سازی رکوردها به صورت اتفاقی در Entity framework
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: دو دقیقه

یکی از انواع روش‌هایی که در SQL Server و مشتقات آن برای نمایش رکوردها به صورت اتفاقی مورد استفاده قرار می‌گیرد، استفاده از کوئری زیر است:
SELECT * FROM table
ORDER BY NEWID()
سؤال: ترجمه و معادل کوئری فوق در Entity framework به چه صورتی است؟
پاسخ:
یک مثال کامل را در این زمینه در ادامه ملاحظه می‌کنید:
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;

namespace Sample
{
    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

    public class MyContext : DbContext
    {
        public DbSet<User> Users { get; set; }
    }

    public class Configuration : DbMigrationsConfiguration<MyContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }

        protected override void Seed(MyContext context)
        {
            context.Users.Add(new User { Name = "User 1", Age = 20 });
            context.Users.Add(new User { Name = "User 2", Age = 25 });
            context.Users.Add(new User { Name = "User 3", Age = 30 });
            context.Users.Add(new User { Name = "User 4", Age = 35 });
            context.Users.Add(new User { Name = "User 5", Age = 40 });
            base.Seed(context);
        }
    }

    public static class Test
    {
        public static void RunTests()
        {
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());

            using (var context = new MyContext())
            {
               var randomListOfUsers =
                        context.Users
                               .Where(person => person.Age >= 25 && person.Age < 40)
                               .OrderBy(person => Guid.NewGuid())
                               .ToList();

               foreach (var person in randomListOfUsers)
                   Console.WriteLine("{0}:{1}", person.Name, person.Age);
            }
        }
    }
}
تنها نکته مهم آن سطر ذیل است که برای مرتب سازی اتفاقی استفاده شده است:
.OrderBy(person => Guid.NewGuid())
که معادل
ORDER BY NEWID()
در SQL Server است.

خروجی SQL تولیدی کوئری LINQ فوق را نیز در ادامه مشاهده می‌کنید:
SELECT 
[Project1].[Id] AS [Id], 
[Project1].[Name] AS [Name], 
[Project1].[Age] AS [Age]
FROM ( SELECT 
NEWID() AS [C1], ------ Guid created here
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name], 
[Extent1].[Age] AS [Age]
FROM [dbo].[Users] AS [Extent1]
WHERE ([Extent1].[Age] >= 25) AND ([Extent1].[Age] < 40)
)  AS [Project1]
ORDER BY [Project1].[C1] ASC  ------ Used for sorting here
  • #
    ‫۱۱ سال و ۱۲ ماه قبل، جمعه ۷ مهر ۱۳۹۱، ساعت ۱۷:۰۰
    مرسی بابت مطلب خوبتون
    اما کاربرد این روش مرتب سازی در کجاست؟
    به شخصه اولین بار است که این روش مرتب سازی را میبینم.
  • #
    ‫۱۱ سال و ۱۲ ماه قبل، جمعه ۷ مهر ۱۳۹۱، ساعت ۲۲:۰۸
    مرسی واقعا مفید بود.
  • #
    ‫۱۱ سال و ۱۲ ماه قبل، شنبه ۸ مهر ۱۳۹۱، ساعت ۱۵:۱۳
    این روش رو جداول حجیم سرعت رو میاره پایین تو محیط sql میشه از TABLESAMPLE استفاده کرد که متاسفانه معادلی براش تو linq نیست و...
    آقای نصیری یه روش هم به این صورته
     SELECT * FROM Table1
      WHERE (ABS(CAST(
      (BINARY_CHECKSUM(*) *
      RAND()) as int)) % 100) < 10
    
     میخواستم بدونم این روش رو میشه به linq تبدیل کرد؟
    • #
      ‫۱۱ سال و ۱۲ ماه قبل، شنبه ۸ مهر ۱۳۹۱، ساعت ۱۶:۱۴
      خیر. کوئری‌های EF طوری طراحی شدن که قابل انتقال به بانک‌های اطلاعاتی دیگر هم باشند و بتونید با تغییر کانکشن استرینگ بدون نگرانی آنچنانی، واقعا از یک بانک اطلاعاتی دیگر استفاده کنید.
      در EF می‌شود raw sql هم نوشت: (^). در این حالت برنامه شما صرفا به بانک اطلاعاتی مورد استفاده گره خواهد خورد و اگر مثلا این BINARY_CHECKSUM در SQLite وجود خارجی نداشت، این برنامه و سیستم دیگر قابل انتقال نخواهند بود.
  • #
    ‫۱۱ سال و ۱۲ ماه قبل، شنبه ۸ مهر ۱۳۹۱، ساعت ۱۹:۳۰
    یه سری دستورات هستند که EF معادلی براشون توی SQL نداره به طور مثال EF نمی‌دونه که متد Parse رو در SQL به چی تبدیل کنه،به طور مثال کد زیر :
    var query = (from list in dbContext.Packages
                                 where list.Id == Int32.Parse(Request["Id"].ToString())
                                 select list).FirstOrDefault();
    باید به صورت زیر تغییر بدیم :
    Int32 ID = Int32.Parse(Request["Id"].ToString());
     var query = (from list in dbContext.Packages
                                 where list.Id == ID
                                 select list).FirstOrDefault();
    به نظرتون توی نسخه‌های بعد این مشکلات رو برطرف می‌کنن؟
    • #
      ‫۱۱ سال و ۱۲ ماه قبل، شنبه ۸ مهر ۱۳۹۱، ساعت ۲۰:۰۹
      لطفا از موضوع بحث که مرتب سازی اتفاقی است خارج نشید.
      در مورد پیشنهادها و انتقادهای مرتبط با EF می‌تونید به اینجا مراجعه کنید: (^)
  • #
    ‫۱۰ سال و ۹ ماه قبل، شنبه ۲۱ دی ۱۳۹۲، ساعت ۲۲:۳۲
    با سلام
    آیا میشود جدولی که هر آیتم آن میتواند لیستی از همین جدول را داشته باشد در entity مرتب کرد؟ مانند یک لیست تو در تو.