LINQ හි ​​“ඇණවුම් කරන්න”


1595

මට වගු දෙකක් ඇති moviesඅතර categories, මම මුලින්ම කාණ්ඩ අංකයෙන් සහ පසුව නම අනුව ඇණවුම් ලැයිස්තුවක් ලබා ගනිමි .

චිත්‍රපට වගුවේ තීරු ID, නම සහ CategoryID යන තීරු තුනක් ඇත . කාණ්ඩ වගුවේ ID සහ නම යන තීරු දෙකක් ඇත .

මම පහත සඳහන් දේ වැනි දෙයක් උත්සාහ කළ නමුත් එය සාර්ථක වූයේ නැත.

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

මෙය ක්‍රියාත්මක කළ නොහැක්කේ මෙන්න: වරහන් තුළ ඇති ලැම්බඩා ප්‍රකාශනය මඟින් අයිතම ඇණවුම් කිරීමට භාවිතා කළ හැකි අගයක් ආපසු ලබා දිය යුතුය: m.CategoryID යනු අයිතම ඇණවුම් කිරීමට භාවිතා කළ හැකි අංකයකි. නමුත් "m.CategoryID, m.Name" මෙම සන්දර්භය තුළ තේරුමක් නැත.
චිකොඩෝරෝ

10
.ඔබ සොයන්නේ කුමක් ද?
eka808

අහම්බෙන් ඔබට ඒවා අවරෝහණ පිළිවෙලට වර්ග කිරීමට අවශ්‍ය නම් මෙහි යා යුතු මාර්ගයයි.
ආර්බීටී

Answers:


2848

මෙය ඔබ වෙනුවෙන් වැඩ කළ යුතුය:

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

4
ඇත්ත වශයෙන්ම පිළිතුරට ස්තූතියි ... නමුත් Var movies = _db.Movies.Orderby(c => c.Category).ThenBy(n => n.Name) මම Var movies = _db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name) 2 වතාවක් "orderBy" භාවිතා කරනවා වෙනුවට ප්‍රති result ලය වෙනස් වන්නේ ඇයි?

148
ve දේවේන්ද්‍ර, ප්‍රති "ලය වෙනස් වන්නේ පළමු" ඕඩර්බයි "හි ප්‍රති result ලය වන එකතුවට වඩා දෙවන" ඕඩර්බයි "ක්‍රියා කරන නිසා සහ එහි අයිතම නැවත

70
මම නොදැන මේ පොළොව මතට ගියේ ThenByකෙසේද?! ( සංස්කරණය කරන්න: ඒ වගේ පෙනුම .NET 4.0 දී, එය අවධානයට ලක් මට පසුගිය ලිස්සා ආකාරය පැහැදිලි කරන හඳුන්වා දෙන ලදී.)
ජෝර්දානය අළු

13
LINQ එකතු කළ දින සිට මෙය පවතී. මෙම පිළිතුර පෙර .NET 4.0 වේ.
නේතන් ඩබ්

10
ඔව්, මම ඉක්මණින් නිගමනය කළේ ප්‍රලේඛන පිටුවේ 3.5 වන අනුවාදයේ පහළට නොපැමිණීම මත ය ; අනුවාද තොරතුරු සඳහා මා සෑම අතින්ම බැලිය යුතුව තිබුණි. නිවැරදි කිරීම සඳහා ස්තූතියි. :)
ජෝර්දාන් ග්‍රේ

597

ලැම්බඩා නොවන, විමසුම්-සින්ටැක්ස් ලින්ක් භාවිතා කරමින් ඔබට මෙය කළ හැකිය:

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

[අදහස් දැක්වීම සඳහා සංස්කරණය කරන්න] වර්ග කිරීමේ අනුපිළිවෙල පාලනය කිරීම සඳහා, මූලික වචන භාවිතා කරන්න ascending(එය පෙරනිමිය වන අතර එබැවින් විශේෂයෙන් ප්‍රයෝජනවත් නොවේ) හෝ descending, එසේ ය:

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

1
මෙම වාක්‍ය ඛණ්ඩය තුළ අවරෝහණ සහ නොවන අතර පෙරළීමට ක්‍රමයක් නොමැත?
ehdv

1
ඇත්තටම, ඔබේ පිළිතුර සමාන වේ _db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name). වඩාත් නිවැරදි වන්නේfrom row in _db.Movies orderby row.Category descending orderby row.Name select row
Lodewijk

9
Ode ලොඩ්විජ්: මම විශ්වාස කරනවා ඔබට එය හරියටම පසුපසට ඇති බව. ඔබේ උදාහරණය පේළියකින් අවසන් වේ. නම ප්‍රාථමික තීරුව සහ පේළිය වේ. ද්විතීයික කාණ්ඩය, එය සමාන වේ _db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name). ඔබ සපයන ස්නිපෙට් දෙක එකිනෙකට සමාන වේ, OP වලට නොවේ.
ස්කොට් ස්ටැෆර්ඩ්

6
ලින්ක් සඳහා SQL සින්ටැක්ස් භාවිතා කිරීමේ එකම අවාසිය නම්, සියලු කාර්යයන් සඳහා සහය නොදක්වන අතර, බොහෝමයක් නමුත් සියල්ලම නොවේ
ජොෂුවා ජී

74

අලුතින් එකතු කරන්න":

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

ඒක මගේ පෙට්ටියේ වැඩ කරනවා. එය වර්ග කිරීම සඳහා භාවිතා කළ හැකි යමක් ආපසු ලබා දෙයි. එය අගයන් දෙකක් සහිත වස්තුවක් ආපසු ලබා දෙයි.

පහත දැක්වෙන පරිදි ඒකාබද්ධ තීරුවකින් වර්ග කිරීමට සමාන, නමුත් වෙනස් වේ.

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

21
අංක සඳහා එය භාවිතා කිරීමේදී ප්‍රවේශම් වන්න.
WoF_Angel

7
ඔබේ අවශ්‍යතාවය අනුව ඔබට OrderByDescending සහ ThenBy, හෝ OrderBy සහ ThenByDescending භාවිතා කළ හැකිය.
අලි ෂා අහමඩ්

6
මම හොඳට බව ඉන්නේ .OrderBy( m => new { m.CategoryID, m.Name })සහ .OrderBy( m => new { m.Name, m.CategoryID })ඒ වෙනුවට අදහස් ප්රමුඛත්වය ගරු වඩා එම ප්රතිඵල සටහන් වනු ඇත. එය සමහර විට අහම්බෙන් ඔබට අවශ්‍ය ඇණවුම ලබා දෙන බවක් පෙනේ. m.CategoryID.ToString() + m.NameCategoryID a නම් ඊට අමතරව වැරදි ඇණවුම් ලබා දෙනු ඇත int. උදාහරණයක් ලෙස, id = 123, name = 5times හැඳුනුම්පත id = 1234 ට පසුව දිස්වනු ඇත, නම = පෙර වෙනුවට යමක්. Int සැසඳීම් සිදුවිය හැකි ස්ථානවල සැසඳීම් කිරීමද අකාර්යක්ෂම නොවේ.
ආරොන්එල්එස්

7
මම නිර්නාමික වර්ගයක් මත ඇණවුම් කිරීමට උත්සාහ කරන විට, "අවම වශයෙන් එක් වස්තුවක් වත් අසමසම ක්‍රියාත්මක කළ යුතුය" යන පණිවිඩය සමඟ මට තර්ක විතර්කයක් ලැබේ. මෙය කරන විට අනෙක් අය සංසන්දකයෙකු ප්‍රකාශ කළ යුතු බව මට පෙනේ. Stackoverflow.com/questions/10356864/… බලන්න .
රොබට් ගොව්ලන්ඩ්

4
මෙය සම්පූර්ණයෙන්ම වැරදිය. ICompariable ක්‍රියාත්මක කිරීමක් නොමැති නව නිර්නාමික වර්ගයකින් ඇණවුම් කිරීම ක්‍රියා කළ නොහැක, මන්ද නිර්නාමික වර්ගයක ගුණාංග වලට අනුපිළිවෙලක් නොමැති බැවිනි. CategoryID පළමුව වර්ග කිරීම හෝ පළමුව නම නම් කිරීම ප්‍රතිවිරුද්ධ අනුපිළිවෙලට වර්ග කළ යුතු දැයි එය නොදනී.
ට්‍රයින්කෝ

30

ඩේටාකොන්ටෙක්ස්ට් හි SQL ක්‍රියාකාරකම් කොන්සෝලය වෙත ලොග් කිරීම සඳහා ඔබේ ඩේටාකොන්ටෙක්ස්ට් හි පහත දැක්වෙන රේඛාව භාවිතා කරන්න - එවිට ඔබේ ලින්ක් ප්‍රකාශයන් දත්ත ගබඩාවෙන් ඉල්ලා සිටින්නේ හරියටම ඔබට දැක ගත හැකිය:

_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]

ෙකෙසේෙවතත්, ලින්ක් හි ඕඩර්බයි එකක් පුනරාවර්තනය කිරීම, එහි ප්‍රති ing ලයක් ෙලස 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

24

මම දීර් extension කිරීමේ ක්‍රම කිහිපයක් (පහළ) නිර්මාණය කර ඇති බැවින් 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);

ඔබ ඇණවුම ගතිකව නිර්මාණය කරන්නේ නම් මෙය විශේෂයෙන් උපකාරී වේ, වර්ග කිරීම සඳහා දේපල ලැයිස්තුවකින් fe.

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);
        }
    }
}

1
මෙම පිළිතුර රන් ය! විමසීම් සඳහා වන චෙක්පත මම ඒකාබද්ධ කරමි. මෙම පෝස්ට් එකේ පිළිතුර සමඟ, වර්ගීකරණ දිශාවක් ගත හැකි තනි ක්‍රමයක් තිබිය යුතුය: stackoverflow.com/questions/388708
ස්විස්කෝඩර්

1
මේ ආකාරයෙන් ලින්ක් ක්‍රියාත්මක කිරීම පළමු තැනට යා යුතුය! OrderBy නරක ලෙස නිර්මාණය කර ඇත ...
Andrzej Martyna

1
Ar මාරි ඔබ පැහැදිලිවම භාවිත නඩුව තේරුම් ගෙන නැත. උදාහරණයක් ලෙස දේපල ලැයිස්තුවකින් ගතිකව ඇණවුමක් නිර්මාණය කරන්නේ කෙසේද? එකම ක්‍රමය මෙයයි. කරුණාකර පහත් කොට නැවත සලකා බලන්න එපා. ඔබට ස්තුතියි.
sjkm

සාමාන්යයෙන් ප්රමාණවත්. මට තවමත් ප්‍රතිලාභයක් නොපෙනේ, නමුත් මම මගේ ඡන්දය ආපසු ගන්නෙමි
මාරි

ශුන්‍ය අගයන් සලකා බැලීම සඳහා ඔබට මෙම දිගුව පහසුවෙන් දිගු කළ හැකිය. වෙත යොමු වන්න: stackoverflow.com/a/36507021
sjkm

16

පහසුම නොවන නමුත් LINQ භාවිතයෙන් මෙය කිරීමට අවම වශයෙන් තවත් ක්‍රමයක් තිබේ. A භාවිතා කරන 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());

ඔබට එක් අයිතමයක් සඳහා ඇණවුම බැසයාමට අවශ්‍ය නම් Compare()MovieComparerඅනුව ක්‍රමවේදය තුළ x සහ y මාරු කරන්න .


1
විවිධ ඇල්ගොරිතම සමඟ විවිධ සංසන්දනාත්මක වස්තූන් තිබීම ඇතුළුව ඔබට සැසඳීම සමඟ අමුතු දේවල් කළ හැකි බැවින් මම ඊට වඩා සාමාන්‍ය දෙයක් ලෙස කැමතියි. IComparable අතුරුමුහුණත ක්‍රියාත්මක කරන පන්තියක් නිර්මාණය කිරීම ගැන ඉගෙන ගැනීමට පෙර මෙය මා කැමති විසඳුමට වඩා හොඳය.
ජෙරාඩ් ඔනිල්

1
2012 සිට (.NET අනුවාදය 4.5) ඔබ MovieComparerවිසින්ම පන්තියක් නිර්මාණය කළ යුතු නැත ; ඒ වෙනුවට ඔබට කළ හැකිය _db.Movies.OrderBy(item => item, Comparer<Movie>.Create((x, y) => { if (x.CategoryId == y.CategoryId) { return x.Name.CompareTo(y.Name); } else { return x.CategoryId.CompareTo(y.CategoryId); } }));. ඇත්ත වශයෙන්ම, ඔබ තර්කනය එක් ප්‍රකාශනයක් ලෙස ලිවීමට කැමති නම්, ඒ වෙනුවට if... else, එවිට ලැම්ඩා (x, y) => exprවඩාත් සරල විය හැකිය.
ජෙප් ස්ටිග් නීල්සන්

3

සාමාන්‍ය නිධිය භාවිතා කරන්නේ නම්

> lstModule = _ModuleRepository.GetAll().OrderBy(x => new { x.Level,
> x.Rank}).ToList();

නැතිනම්

> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();

1
නිර්නාමික ප්‍රකාශන දේශීය රාමු හරය මඟින් දේශීයව විග්‍රහ කරනු ලැබේ. LINQ ප්‍රකාශනය පරිවර්තනය කළ නොහැකි අතර එය දේශීයව ඇගයීමට ලක් කෙරේ.
alhpe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.