sql-order-by - متعدد "ترتيب" في LINQ




(6)

هذا يجب أن تعمل من أجلك:

var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)

لدي جدولين movies categories ، وأحصل على قائمة مرتبة حسب الفئة الأولى ثم بالاسم .

يحتوي جدول الفيلم على ثلاثة أعمدة ، معرّف ، اسم ، و CategoryID . يحتوي جدول الفئات 2 على أعمدة ومعرف واسم .

جربت ما يشبه ما يلي ، لكنه لم ينجح.

var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })

هناك طريقة واحدة أخرى على الأقل للقيام بذلك باستخدام LINQ ، على الرغم من أنه ليس الأسهل. يمكنك القيام بذلك باستخدام أسلوب OrberBy() يستخدم IComparer . أولاً تحتاج إلى تنفيذ IComparer لفئة Movie مثل هذا:

public class MovieComparer : IComparer<Movie>
{
    public int Compare(Movie x, Movie y)
    {
        if (x.CategoryId == y.CategoryId)
        {
            return x.Name.CompareTo(y.Name);
        }
        else
        {
            return x.CategoryId.CompareTo(y.CategoryId);
        }
    }
}

بعد ذلك يمكنك طلب الأفلام باستخدام الصيغة التالية:

var movies = _db.Movies.OrderBy(item => item, new MovieComparer());

إذا كنت بحاجة إلى تبديل الترتيب إلى تنازلي لأحد العناصر ، MovieComparer فقط بتبديل x و y داخل الأسلوب Compare() الخاص بـ MovieComparer وفقًا لذلك.


استخدم السطر التالي على DataContext الخاص بك لتسجيل نشاط SQL على DataContext إلى وحدة التحكم - ثم يمكنك أن ترى بالضبط ما يطلب بيانات linq من قاعدة البيانات:

_db.Log = Console.Out

عبارات LINQ التالية:

var movies = from row in _db.Movies 
             orderby row.CategoryID, row.Name
             select row;

و

var movies = _db.Movies.OrderBy(m => m.CategoryID).ThenBy(m => m.Name);

إنتاج SQL التالي:

SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].CategoryID, [t0].[Name]

حيث أن تكرار OrderBy في Linq يظهر عكس ناتج SQL الناتج:

var movies = from row in _db.Movies 
             orderby row.CategoryID
             orderby row.Name
             select row;

و

var movies = _db.Movies.OrderBy(m => m.CategoryID).OrderBy(m => m.Name);

إنتاج SQL التالي (يتم تبديل اسم و CategoryId):

SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].[Name], [t0].CategoryID

لقد قمت بإنشاء بعض طرق الإضافة (أدناه) ، لذلك لا داعي للقلق إذا تم طلب الحصول على IQueryable بالفعل أم لا. إذا كنت ترغب في الترتيب بواسطة خصائص متعددة ، فقم بذلك كما يلي:

// We do not have to care if the queryable is already sorted or not. 
// The order of the Smart* calls defines the order priority
queryable.SmartOrderBy(i => i.Property1).SmartOrderByDescending(i => i.Property2);

يكون هذا مفيدًا بشكل خاص إذا قمت بإنشاء الترتيب ديناميكيًا ، من قائمة خصائص لفرزها.

public static class IQueryableExtension
{
    public static bool IsOrdered<T>(this IQueryable<T> queryable) {
        if(queryable == null) {
            throw new ArgumentNullException("queryable");
        }

        return queryable.Expression.Type == typeof(IOrderedQueryable<T>);
    }

    public static IQueryable<T> SmartOrderBy<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
        if(queryable.IsOrdered()) {
            var orderedQuery = queryable as IOrderedQueryable<T>;
            return orderedQuery.ThenBy(keySelector);
        } else {
            return queryable.OrderBy(keySelector);
        }
    }

    public static IQueryable<T> SmartOrderByDescending<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
        if(queryable.IsOrdered()) {
            var orderedQuery = queryable as IOrderedQueryable<T>;
            return orderedQuery.ThenByDescending(keySelector);
        } else {
            return queryable.OrderByDescending(keySelector);
        }
    }
}

اضف جديد":

var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })

هذا يعمل على مربع بلدي. إنها تعيد شيئًا يمكن استخدامه للفرز. تقوم بإرجاع كائن بقيمتين.

مماثلة ، ولكنها تختلف عن الفرز بعمود مشترك ، على النحو التالي.

var movies = _db.Movies.OrderBy( m => (m.CategoryID.ToString() + m.Name))

في عقيدة 2.x لا يمكنك تمرير ترتيب متعدد باستخدام "orderBy" أو "addOrderBy" على النحو الوارد أعلاه. لأنه يضيف تلقائيًا "ASC" في نهاية اسم العمود الأخير عندما تترك المعلمة الثانية فارغة ، كما هو الحال في الدالة "orderBy".

على سبيل المثال ->orderBy('a.fist_name ASC, a.last_name ASC') SQL شيء مثل هذا 'ORDER BY first_name ASC، last_name ASC ASC'. لذلك هذا خطأ في بناء جملة SQL. ببساطة لأن الافتراضي orderBy أو addOrderBy هو "ASC".

لإضافة ترتيب متعدد من قبل ، تحتاج إلى استخدام وظيفة "إضافة". وسوف يكون من هذا القبيل.

->add('orderBy','first_name ASC, last_name ASC') . هذا سوف يعطيك SQL المنسقة بشكل صحيح.

مزيد من المعلومات عن الوظيفة (). http://www.doctrine-project.org/api/orm/2.2/class-Doctrine.ORM.QueryBuilder.html#_add

أتمنى أن يساعدك هذا. في صحتك!







linq sql-order-by