AMcoder - javascript, python, java, html, php, sql

Տարբերություն այն բանի, թե ինչպես է LINQ-ը կազմակերպություններին և LINQ-ին օբյեկտներին մշակում նկարահանումները

Վերջերս ես միացա մի նախագծի, որտեղ Sort մեթոդը պայմանականորեն անցնում էր լամբդա արտահայտությունով LINQ հարցմանը, որպեսզի որոշի, թե որ հատկությունը պետք է տեսակավորվի: Խնդիրն այն էր, որ lambda արտահայտությունը փոխանցվում էր Func<TEntity, Object>-ով և ոչ թե Expression<Func<TEntity, Object>>-ով, այնպես որ տեսակավորումը տեղի էր ունենում հիշողության մեջ և ոչ թե տվյալների բազայում (որովհետև OrderBy-ի գերբեռնվածությունը, որը վերցնում է IEnumerable կոչվում է): Սա SortWithDelegate տարբերակն է (տես ստորև):

Երբ ես օգտագործում եմ Expression<Func<TEntity, Object>>-ը (տես SortWithExpression ստորև), այնուհետև, երբ տողի հատկությունը փոխանցվում է orderBy պարամետրում, պատվերը ճիշտ է կատարվում տվյալների բազայում: Այնուամենայնիվ, երբ ես փորձում եմ տեսակավորել ամբողջ թվով (կամ ամսաթիվը) օգտագործելով Expression<Func<TEntity, Object>>, ես ստանում եմ հետևյալ սխալը.

Unable to cast the type 'System.Int32' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.

Սրանից խուսափելու համար ես պետք է փաթաթեմ ամբողջ թվի կամ ամսաթվերի դաշտը, որը պետք է տեսակավորվի անանուն տիպի ներսում, ինչպես օրինակ՝ orderByFunc = sl => new {sl.ParentUnit.Id};: Ես հասկանում եմ, որ պետք է դա անեմ, քանի որ Func-ի վերադարձի տեսակը Object է: Այնուամենայնիվ, այն, ինչ ես չեմ հասկանում, այն է, թե ինչու ես պետք է դա անեմ, երբ աշխատում եմ LINQ to Entities մատակարարի հետ, բայց ոչ LINQ to Objects մատակարարի հետ:

void Main()
{
    var _context = new MyContext();

    string sortProperty = "Id";
    bool sortAscending = false;


    IQueryable<Qualification> qualifications = _context.Qualifications.Include(q => q.ParentUnit);

    qualifications = SortWithExpression(sortProperty, sortAscending, qualifications);

    qualifications.Dump();

}

private static IQueryable<Qualification> SortWithDelegate(string orderBy, bool sortAscending, IQueryable<Qualification> qualificationsQuery)
{
    Func<Qualification, Object> orderByFunc;

    switch (orderBy)
    {
        case "Name":
            orderByFunc = sl => sl.Name;
            break;
        case "ParentUnit":
            orderByFunc = sl => sl.ParentUnit.Name;
            break;
        case "Id":
            orderByFunc = sl => sl.ParentUnit.Id;
            break;
        case "Created":
            orderByFunc = sl => sl.Created;
            break;
        default:
            orderByFunc = sl => sl.Name;
            break;
    }

    qualificationsQuery = sortAscending
        ? qualificationsQuery.OrderBy(orderByFunc).AsQueryable()
            : qualificationsQuery.OrderByDescending(orderByFunc).AsQueryable();

    return qualificationsQuery;
}

private static IQueryable<Qualification> SortWithExpression(string orderBy, bool sortAscending, IQueryable<Qualification> qualificationsQuery)
{
    Expression<Func<Qualification, Object>> orderByFunc;

    switch (orderBy)
    {
        case "Name":
            orderByFunc = sl => sl.Name;
            break;
        case "ParentUnit":
            orderByFunc = sl => sl.ParentUnit.Name;
            break;
        case "Id":
            orderByFunc = sl => new {sl.ParentUnit.Id};
            break;
        case "Created":
            orderByFunc = sl => new {sl.Created};
            break;
        default:
            orderByFunc = sl => sl.Name;
            break;
    }

    qualificationsQuery = sortAscending
        ? qualificationsQuery.OrderBy(orderByFunc)
            : qualificationsQuery.OrderByDescending(orderByFunc);

    return qualificationsQuery;
}

Ավելացված է

Պարզապես մտածեցի, որ այս խնդրին կավելացնեմ իմ սեփական լուծումը: int և datetime բռնցքամարտից խուսափելու համար ես IQueryable<T>-ի վրա ստեղծել եմ ընդհանուր ընդլայնման մեթոդ, որին անցնում եմ լամբդա արտահայտությունով՝ ցույց տալու տեսակավորման դաշտը և բուլյան՝ նշելով, թե արդյոք տեսակավորման կարգը պետք է լինի աճողական, թե ոչ:

    public static IQueryable<TSource> OrderBy<TSource, TResult>(this IQueryable<TSource> query, Expression<Func<TSource, TResult>> func, bool sortAscending)
    {
        return sortAscending ?
            query.OrderBy(func) :
                query.OrderByDescending(func);
    }

    private static IQueryable<Qualification> Sort(string orderBy, bool sortAscending, IQueryable<Qualification> qualificationsQuery)
    {
        switch (orderBy)
        {
            case "Name":
                return qualificationsQuery.OrderBy(sl => sl.Name, sortAscending);
            case "ParentUnit":
                return qualificationsQuery.OrderBy(s1 => s1.ParentUnit.Name, sortAscending);
            default:
                return qualificationsQuery.OrderBy(sl => sl.Name, sortAscending);
        }
    }

  • ինչու չանել google-ի որոնում սխալի վերաբերյալ, և դա շատ օրինակներ կտա, թե ինչ կարող եք անել ձեր առջև ծառացած այս խնդիրը շտկելու համար: 22.12.2014
  • Ես կարող եմ աշխատել այս հարցի շուրջ: Իմ հարցի նպատակն էր հետաքրքրվել, թե ինչու կա տարբերություն, թե ինչպես են LINQ-to-Entities-ը և LINQ-to-Objects-ը նման կերպ վարվում տիպերի հետ: 22.12.2014

Պատասխանները:


1

Արտահայտման ծառերը, ինչպես ենթադրում է նրանց անունը, արտահայտություն են ինչ-որ բան անելու մասին: Դուք կարող եք այցելել արտահայտությունները և մեկնաբանել դրանք ձեր սեփական բիզնեսի համար, կամ լամբդա արտահայտությունների նման կարող եք դրանք կազմել և կանչել որպես պատվիրակ:

Երբ դուք փոխանցում եք orderby մեթոդի արտահայտությունը Linq-ում Entities-ին, այն կայցելի Linq-ը Entities-ին և ձեր դեպքում կստեղծվի «Int32 to Object» բացառությունը, քանի որ այն մեկնաբանվում է որպես MemberInfo, որը վերածվում է սյունակի անվանման: տվյալների բազայի հարցման համար: Բայց երբ այն օգտագործում եք որպես Func-ի պատվիրակ, այն չի կարող թարգմանվել, և այն կկանչվի որպես պատվիրակ՝ orderby մեթոդի տեսակավորման ալգորիթմի համեմատության համար:

22.12.2014
  • քանի որ այն մեկնաբանվում է որպես MemberInfo, որը վերածվում է տվյալների բազայի հարցման սյունակի անվանման, սա այն է, ինչ ես փնտրում էի: Շնորհակալություն 22.12.2014
  • Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..