C# Expression to sort generic query by key fieldC# Expression to use Guid bookmarkHow can I detect if this dictionary key exists in C#?IEnumerable vs List - What to Use? How do they work?C# Pass Lambda Expression as Method ParameterWhy not inherit from List<T>?Dynamically Create Sort Lambda ExpressionHow do I create an Expression out of another Expression in C#?IQueryable Expression TranslationC# Pass lambda expression field into method and use field in linq queryDynamic Expression Generation Issues with ValueTypesC# Use lambda expression to get parameter name of method

Avoiding repetition when using the "snprintf idiom" to write text

Could you fall off a planet if it was being accelerated by engines?

Checkmate in 1 on a Tangled Board

ATMEGA328P-U vs ATMEGA328-PU

Tricolour nonogram

What is the meaning of "it" in "as luck would have it"?

"in 60 seconds or less" or "in 60 seconds or fewer"?

Odd PCB Layout for Voltage Regulator

Why would Dementors torture a Death Eater if they are loyal to Voldemort?

Any Tips On Writing Extended Recollection In A Novel

Word ending in "-ine" for rat-like

Why are examinees often not allowed to leave during the start and end of an exam?

Position representation of spin states and spin operators

Why is my 401k manager recommending me to save more?

I agreed to cancel a long-planned vacation (with travel costs) due to project deadlines, but now the timeline has all changed again

Are you required to spend hit dice to take a short rest?

Where to connect the fuse and why?

How can this fractal shape perfectly cover a certain platonic solid?

Can a quantum computer run classical algorithms?

Why do movie directors use brown tint on Mexico cities?

Why was Pan Am Flight 103 flying over Lockerbie?

How soon after takeoff can you recline your airplane seat?

Why should I allow multiple IP addresses on a website for a single session?

Why isn't UDP with reliability (implemented at Application layer) a substitute of TCP?



C# Expression to sort generic query by key field


C# Expression to use Guid bookmarkHow can I detect if this dictionary key exists in C#?IEnumerable vs List - What to Use? How do they work?C# Pass Lambda Expression as Method ParameterWhy not inherit from List<T>?Dynamically Create Sort Lambda ExpressionHow do I create an Expression out of another Expression in C#?IQueryable Expression TranslationC# Pass lambda expression field into method and use field in linq queryDynamic Expression Generation Issues with ValueTypesC# Use lambda expression to get parameter name of method













3















I have a generic method in which I want to sort an IQueryable<T> by its key field (it is safe to assume there is only one). Thus:



void DoStuff<T>(...) 

IQueryable<T> queryable = ... // given
PropertyInfo keyField = ... // given
var sortedQueryable = queryable.OrderBy(<some expression here>);
...



How do I define an Expression that will return the keyField property of T so that this will work?










share|improve this question

















  • 2





    @Fabjan Of course it's possible with expressions.

    – DavidG
    Mar 25 at 16:35











  • @DavidG The problem here is not expression itself but the engine that will try to convert it to SQL such as Linq To SQL or other

    – Fabjan
    Mar 25 at 16:36












  • @Fabjan I know, I'm saying it's possible to build an expression to do it - I've done this myself more than once.

    – DavidG
    Mar 25 at 16:37











  • @DavidG You would better write a good answer to this question then if you know exactly how to do it

    – Fabjan
    Mar 25 at 16:39







  • 1





    @Fabjan OK, done.

    – DavidG
    Mar 25 at 16:45















3















I have a generic method in which I want to sort an IQueryable<T> by its key field (it is safe to assume there is only one). Thus:



void DoStuff<T>(...) 

IQueryable<T> queryable = ... // given
PropertyInfo keyField = ... // given
var sortedQueryable = queryable.OrderBy(<some expression here>);
...



How do I define an Expression that will return the keyField property of T so that this will work?










share|improve this question

















  • 2





    @Fabjan Of course it's possible with expressions.

    – DavidG
    Mar 25 at 16:35











  • @DavidG The problem here is not expression itself but the engine that will try to convert it to SQL such as Linq To SQL or other

    – Fabjan
    Mar 25 at 16:36












  • @Fabjan I know, I'm saying it's possible to build an expression to do it - I've done this myself more than once.

    – DavidG
    Mar 25 at 16:37











  • @DavidG You would better write a good answer to this question then if you know exactly how to do it

    – Fabjan
    Mar 25 at 16:39







  • 1





    @Fabjan OK, done.

    – DavidG
    Mar 25 at 16:45













3












3








3


2






I have a generic method in which I want to sort an IQueryable<T> by its key field (it is safe to assume there is only one). Thus:



void DoStuff<T>(...) 

IQueryable<T> queryable = ... // given
PropertyInfo keyField = ... // given
var sortedQueryable = queryable.OrderBy(<some expression here>);
...



How do I define an Expression that will return the keyField property of T so that this will work?










share|improve this question














I have a generic method in which I want to sort an IQueryable<T> by its key field (it is safe to assume there is only one). Thus:



void DoStuff<T>(...) 

IQueryable<T> queryable = ... // given
PropertyInfo keyField = ... // given
var sortedQueryable = queryable.OrderBy(<some expression here>);
...



How do I define an Expression that will return the keyField property of T so that this will work?







c# linq linq-expressions






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 25 at 16:26









Shaul BehrShaul Behr

17.1k57 gold badges208 silver badges328 bronze badges




17.1k57 gold badges208 silver badges328 bronze badges







  • 2





    @Fabjan Of course it's possible with expressions.

    – DavidG
    Mar 25 at 16:35











  • @DavidG The problem here is not expression itself but the engine that will try to convert it to SQL such as Linq To SQL or other

    – Fabjan
    Mar 25 at 16:36












  • @Fabjan I know, I'm saying it's possible to build an expression to do it - I've done this myself more than once.

    – DavidG
    Mar 25 at 16:37











  • @DavidG You would better write a good answer to this question then if you know exactly how to do it

    – Fabjan
    Mar 25 at 16:39







  • 1





    @Fabjan OK, done.

    – DavidG
    Mar 25 at 16:45












  • 2





    @Fabjan Of course it's possible with expressions.

    – DavidG
    Mar 25 at 16:35











  • @DavidG The problem here is not expression itself but the engine that will try to convert it to SQL such as Linq To SQL or other

    – Fabjan
    Mar 25 at 16:36












  • @Fabjan I know, I'm saying it's possible to build an expression to do it - I've done this myself more than once.

    – DavidG
    Mar 25 at 16:37











  • @DavidG You would better write a good answer to this question then if you know exactly how to do it

    – Fabjan
    Mar 25 at 16:39







  • 1





    @Fabjan OK, done.

    – DavidG
    Mar 25 at 16:45







2




2





@Fabjan Of course it's possible with expressions.

– DavidG
Mar 25 at 16:35





@Fabjan Of course it's possible with expressions.

– DavidG
Mar 25 at 16:35













@DavidG The problem here is not expression itself but the engine that will try to convert it to SQL such as Linq To SQL or other

– Fabjan
Mar 25 at 16:36






@DavidG The problem here is not expression itself but the engine that will try to convert it to SQL such as Linq To SQL or other

– Fabjan
Mar 25 at 16:36














@Fabjan I know, I'm saying it's possible to build an expression to do it - I've done this myself more than once.

– DavidG
Mar 25 at 16:37





@Fabjan I know, I'm saying it's possible to build an expression to do it - I've done this myself more than once.

– DavidG
Mar 25 at 16:37













@DavidG You would better write a good answer to this question then if you know exactly how to do it

– Fabjan
Mar 25 at 16:39






@DavidG You would better write a good answer to this question then if you know exactly how to do it

– Fabjan
Mar 25 at 16:39





1




1





@Fabjan OK, done.

– DavidG
Mar 25 at 16:45





@Fabjan OK, done.

– DavidG
Mar 25 at 16:45










3 Answers
3






active

oldest

votes


















8














This isn't too difficult, but you need to invoke the OrderBy with reflection as you don't know the type of the key field ahead of time. So given the code you already show, you would do something like this:



// Build up the property expression to pass into the OrderBy method
var parameterExp = Expression.Parameter(typeof(T), "x");
var propertyExp = Expression.Property(parameterExp, keyField);
var orderByExp = Expression.Lambda(propertyExp, parameterExp);

// Note here you can output "orderByExp.ToString()" which will give you this:
// x => x.NameOfProperty

// Now call the OrderBy via reflection, you can decide here if you want
// "OrderBy" or "OrderByDescending"
var orderByMethodGeneric = typeof(Queryable)
.GetMethods()
.Single(mi => mi.Name == "OrderBy" && mi.GetParameters().Length == 2);

var orderByMethod = orderByMethodGeneric.MakeGenericMethod(typeof(T), propertyExp.Type);

// Get the result
var sortedQueryable = (IQueryable<T>)orderByMethod
.Invoke(null, new object[] queryable, orderByExp );





share|improve this answer























  • Can't we just build the Expression<Func<TEntity, TProp>> instead and pass it to the "normal" OrderBy() method?

    – haim770
    Mar 25 at 16:50











  • @haim770 Sure if you know the type of TProp ahead of time. I'm assuming we don't

    – DavidG
    Mar 25 at 16:50






  • 1





    You're right. But since DoStuff<T>() does define a generic parameter than can be resolved as TEntity, there's a chance keyField points to a property of constant type that can be resolved as TProp. Anyway, great answer.

    – haim770
    Mar 25 at 17:01











  • @haim770 I was assuming keyField is somehow pulled out of the EF model, it's hard to guess without OPs code for doing that.

    – DavidG
    Mar 25 at 17:02






  • 2





    Wow, nicely done

    – Fabjan
    Mar 25 at 18:05


















1














Same idea as in DavidG answer but different approach



// build lambda expression (T t) => t.KeyField
var type = typeof(T);
var parameter = Expression.Parameter(type, "k");
var lambda = Expression.Lambda(Expression.Property(parameter, keyField), parameter);

// get source expression
var baseExpression = queryable.Expression;

// call to OrderBy
var orderByCall = Expression.Call(
typeof(Queryable),
"OrderBy",
new[] type, keyField.PropertyType,
baseExpression, lambda
);

// sorted result
var sorted = queryable.Provider.CreateQuery<T>(orderByCall);





share|improve this answer






























    1














    I like to use an interface IBaseEntity that has an Id property of type T. That would make your query:



    void DoStuff<IBaseEntity>(...) 

    IQueryable<IBaseEntity> queryable = ... // given
    var sortedQueryable = queryable.OrderById(e=> e.Id); //extension method
    ...



    Extension Method:



    public static IQueryable<IBaseEntity<T>> OrderById<T>(this IQueryable<IBaseEntity<T>> query)

    return query.OrderBy(e => e.Id);



    Each entity would implement IBaseEntity and have something like



    public partial class MyEntity : IBaseEntity<long>

    [Required]
    public override long Id

    get return base.Id;
    set base.Id = value;




    Then in the context



    modelBuilder
    .Entity<MyEntity>()
    .ToTable("DatabaseTable", "DatabaseSchema")
    .HasKey(e => e.Id)
    .Property(e => e.Id)
    .HasColumnName("DatabasePrimaryKey")
    .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);


    Note: This requires some setup in the context and entities. The database can have whatever keys you want, you're mapping them individually to the property Id in the OnModelCreating method of the context.






    share|improve this answer

























    • This is OK if you know the name of the property is always going to be the same. In practice though, this is rarely the case.

      – DavidG
      Mar 25 at 16:46











    • As @DavidG says, my key fields are all named differently, i.e. CustomerId, InvoiceId etc.

      – Shaul Behr
      Mar 25 at 16:47











    • @ShaulBehr - I use the context to make the keys the same as far as entity framework is concerned, but they map to the named primary key in the database.

      – Noel
      Mar 25 at 17:03











    • Doesn't help if the property type isn't consistent. It may be int for one entity but Guid or string elsewhere.

      – DavidG
      Mar 25 at 18:13











    • @DavidG - I simplified in the answer, but what we've done is IBaseEntity<T> Where T is the type of primary key

      – Noel
      Mar 25 at 18:32













    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55342324%2fc-sharp-expression-to-sort-generic-query-by-key-field%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    8














    This isn't too difficult, but you need to invoke the OrderBy with reflection as you don't know the type of the key field ahead of time. So given the code you already show, you would do something like this:



    // Build up the property expression to pass into the OrderBy method
    var parameterExp = Expression.Parameter(typeof(T), "x");
    var propertyExp = Expression.Property(parameterExp, keyField);
    var orderByExp = Expression.Lambda(propertyExp, parameterExp);

    // Note here you can output "orderByExp.ToString()" which will give you this:
    // x => x.NameOfProperty

    // Now call the OrderBy via reflection, you can decide here if you want
    // "OrderBy" or "OrderByDescending"
    var orderByMethodGeneric = typeof(Queryable)
    .GetMethods()
    .Single(mi => mi.Name == "OrderBy" && mi.GetParameters().Length == 2);

    var orderByMethod = orderByMethodGeneric.MakeGenericMethod(typeof(T), propertyExp.Type);

    // Get the result
    var sortedQueryable = (IQueryable<T>)orderByMethod
    .Invoke(null, new object[] queryable, orderByExp );





    share|improve this answer























    • Can't we just build the Expression<Func<TEntity, TProp>> instead and pass it to the "normal" OrderBy() method?

      – haim770
      Mar 25 at 16:50











    • @haim770 Sure if you know the type of TProp ahead of time. I'm assuming we don't

      – DavidG
      Mar 25 at 16:50






    • 1





      You're right. But since DoStuff<T>() does define a generic parameter than can be resolved as TEntity, there's a chance keyField points to a property of constant type that can be resolved as TProp. Anyway, great answer.

      – haim770
      Mar 25 at 17:01











    • @haim770 I was assuming keyField is somehow pulled out of the EF model, it's hard to guess without OPs code for doing that.

      – DavidG
      Mar 25 at 17:02






    • 2





      Wow, nicely done

      – Fabjan
      Mar 25 at 18:05















    8














    This isn't too difficult, but you need to invoke the OrderBy with reflection as you don't know the type of the key field ahead of time. So given the code you already show, you would do something like this:



    // Build up the property expression to pass into the OrderBy method
    var parameterExp = Expression.Parameter(typeof(T), "x");
    var propertyExp = Expression.Property(parameterExp, keyField);
    var orderByExp = Expression.Lambda(propertyExp, parameterExp);

    // Note here you can output "orderByExp.ToString()" which will give you this:
    // x => x.NameOfProperty

    // Now call the OrderBy via reflection, you can decide here if you want
    // "OrderBy" or "OrderByDescending"
    var orderByMethodGeneric = typeof(Queryable)
    .GetMethods()
    .Single(mi => mi.Name == "OrderBy" && mi.GetParameters().Length == 2);

    var orderByMethod = orderByMethodGeneric.MakeGenericMethod(typeof(T), propertyExp.Type);

    // Get the result
    var sortedQueryable = (IQueryable<T>)orderByMethod
    .Invoke(null, new object[] queryable, orderByExp );





    share|improve this answer























    • Can't we just build the Expression<Func<TEntity, TProp>> instead and pass it to the "normal" OrderBy() method?

      – haim770
      Mar 25 at 16:50











    • @haim770 Sure if you know the type of TProp ahead of time. I'm assuming we don't

      – DavidG
      Mar 25 at 16:50






    • 1





      You're right. But since DoStuff<T>() does define a generic parameter than can be resolved as TEntity, there's a chance keyField points to a property of constant type that can be resolved as TProp. Anyway, great answer.

      – haim770
      Mar 25 at 17:01











    • @haim770 I was assuming keyField is somehow pulled out of the EF model, it's hard to guess without OPs code for doing that.

      – DavidG
      Mar 25 at 17:02






    • 2





      Wow, nicely done

      – Fabjan
      Mar 25 at 18:05













    8












    8








    8







    This isn't too difficult, but you need to invoke the OrderBy with reflection as you don't know the type of the key field ahead of time. So given the code you already show, you would do something like this:



    // Build up the property expression to pass into the OrderBy method
    var parameterExp = Expression.Parameter(typeof(T), "x");
    var propertyExp = Expression.Property(parameterExp, keyField);
    var orderByExp = Expression.Lambda(propertyExp, parameterExp);

    // Note here you can output "orderByExp.ToString()" which will give you this:
    // x => x.NameOfProperty

    // Now call the OrderBy via reflection, you can decide here if you want
    // "OrderBy" or "OrderByDescending"
    var orderByMethodGeneric = typeof(Queryable)
    .GetMethods()
    .Single(mi => mi.Name == "OrderBy" && mi.GetParameters().Length == 2);

    var orderByMethod = orderByMethodGeneric.MakeGenericMethod(typeof(T), propertyExp.Type);

    // Get the result
    var sortedQueryable = (IQueryable<T>)orderByMethod
    .Invoke(null, new object[] queryable, orderByExp );





    share|improve this answer













    This isn't too difficult, but you need to invoke the OrderBy with reflection as you don't know the type of the key field ahead of time. So given the code you already show, you would do something like this:



    // Build up the property expression to pass into the OrderBy method
    var parameterExp = Expression.Parameter(typeof(T), "x");
    var propertyExp = Expression.Property(parameterExp, keyField);
    var orderByExp = Expression.Lambda(propertyExp, parameterExp);

    // Note here you can output "orderByExp.ToString()" which will give you this:
    // x => x.NameOfProperty

    // Now call the OrderBy via reflection, you can decide here if you want
    // "OrderBy" or "OrderByDescending"
    var orderByMethodGeneric = typeof(Queryable)
    .GetMethods()
    .Single(mi => mi.Name == "OrderBy" && mi.GetParameters().Length == 2);

    var orderByMethod = orderByMethodGeneric.MakeGenericMethod(typeof(T), propertyExp.Type);

    // Get the result
    var sortedQueryable = (IQueryable<T>)orderByMethod
    .Invoke(null, new object[] queryable, orderByExp );






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 25 at 16:45









    DavidGDavidG

    76.2k9 gold badges126 silver badges141 bronze badges




    76.2k9 gold badges126 silver badges141 bronze badges












    • Can't we just build the Expression<Func<TEntity, TProp>> instead and pass it to the "normal" OrderBy() method?

      – haim770
      Mar 25 at 16:50











    • @haim770 Sure if you know the type of TProp ahead of time. I'm assuming we don't

      – DavidG
      Mar 25 at 16:50






    • 1





      You're right. But since DoStuff<T>() does define a generic parameter than can be resolved as TEntity, there's a chance keyField points to a property of constant type that can be resolved as TProp. Anyway, great answer.

      – haim770
      Mar 25 at 17:01











    • @haim770 I was assuming keyField is somehow pulled out of the EF model, it's hard to guess without OPs code for doing that.

      – DavidG
      Mar 25 at 17:02






    • 2





      Wow, nicely done

      – Fabjan
      Mar 25 at 18:05

















    • Can't we just build the Expression<Func<TEntity, TProp>> instead and pass it to the "normal" OrderBy() method?

      – haim770
      Mar 25 at 16:50











    • @haim770 Sure if you know the type of TProp ahead of time. I'm assuming we don't

      – DavidG
      Mar 25 at 16:50






    • 1





      You're right. But since DoStuff<T>() does define a generic parameter than can be resolved as TEntity, there's a chance keyField points to a property of constant type that can be resolved as TProp. Anyway, great answer.

      – haim770
      Mar 25 at 17:01











    • @haim770 I was assuming keyField is somehow pulled out of the EF model, it's hard to guess without OPs code for doing that.

      – DavidG
      Mar 25 at 17:02






    • 2





      Wow, nicely done

      – Fabjan
      Mar 25 at 18:05
















    Can't we just build the Expression<Func<TEntity, TProp>> instead and pass it to the "normal" OrderBy() method?

    – haim770
    Mar 25 at 16:50





    Can't we just build the Expression<Func<TEntity, TProp>> instead and pass it to the "normal" OrderBy() method?

    – haim770
    Mar 25 at 16:50













    @haim770 Sure if you know the type of TProp ahead of time. I'm assuming we don't

    – DavidG
    Mar 25 at 16:50





    @haim770 Sure if you know the type of TProp ahead of time. I'm assuming we don't

    – DavidG
    Mar 25 at 16:50




    1




    1





    You're right. But since DoStuff<T>() does define a generic parameter than can be resolved as TEntity, there's a chance keyField points to a property of constant type that can be resolved as TProp. Anyway, great answer.

    – haim770
    Mar 25 at 17:01





    You're right. But since DoStuff<T>() does define a generic parameter than can be resolved as TEntity, there's a chance keyField points to a property of constant type that can be resolved as TProp. Anyway, great answer.

    – haim770
    Mar 25 at 17:01













    @haim770 I was assuming keyField is somehow pulled out of the EF model, it's hard to guess without OPs code for doing that.

    – DavidG
    Mar 25 at 17:02





    @haim770 I was assuming keyField is somehow pulled out of the EF model, it's hard to guess without OPs code for doing that.

    – DavidG
    Mar 25 at 17:02




    2




    2





    Wow, nicely done

    – Fabjan
    Mar 25 at 18:05





    Wow, nicely done

    – Fabjan
    Mar 25 at 18:05











    1














    Same idea as in DavidG answer but different approach



    // build lambda expression (T t) => t.KeyField
    var type = typeof(T);
    var parameter = Expression.Parameter(type, "k");
    var lambda = Expression.Lambda(Expression.Property(parameter, keyField), parameter);

    // get source expression
    var baseExpression = queryable.Expression;

    // call to OrderBy
    var orderByCall = Expression.Call(
    typeof(Queryable),
    "OrderBy",
    new[] type, keyField.PropertyType,
    baseExpression, lambda
    );

    // sorted result
    var sorted = queryable.Provider.CreateQuery<T>(orderByCall);





    share|improve this answer



























      1














      Same idea as in DavidG answer but different approach



      // build lambda expression (T t) => t.KeyField
      var type = typeof(T);
      var parameter = Expression.Parameter(type, "k");
      var lambda = Expression.Lambda(Expression.Property(parameter, keyField), parameter);

      // get source expression
      var baseExpression = queryable.Expression;

      // call to OrderBy
      var orderByCall = Expression.Call(
      typeof(Queryable),
      "OrderBy",
      new[] type, keyField.PropertyType,
      baseExpression, lambda
      );

      // sorted result
      var sorted = queryable.Provider.CreateQuery<T>(orderByCall);





      share|improve this answer

























        1












        1








        1







        Same idea as in DavidG answer but different approach



        // build lambda expression (T t) => t.KeyField
        var type = typeof(T);
        var parameter = Expression.Parameter(type, "k");
        var lambda = Expression.Lambda(Expression.Property(parameter, keyField), parameter);

        // get source expression
        var baseExpression = queryable.Expression;

        // call to OrderBy
        var orderByCall = Expression.Call(
        typeof(Queryable),
        "OrderBy",
        new[] type, keyField.PropertyType,
        baseExpression, lambda
        );

        // sorted result
        var sorted = queryable.Provider.CreateQuery<T>(orderByCall);





        share|improve this answer













        Same idea as in DavidG answer but different approach



        // build lambda expression (T t) => t.KeyField
        var type = typeof(T);
        var parameter = Expression.Parameter(type, "k");
        var lambda = Expression.Lambda(Expression.Property(parameter, keyField), parameter);

        // get source expression
        var baseExpression = queryable.Expression;

        // call to OrderBy
        var orderByCall = Expression.Call(
        typeof(Queryable),
        "OrderBy",
        new[] type, keyField.PropertyType,
        baseExpression, lambda
        );

        // sorted result
        var sorted = queryable.Provider.CreateQuery<T>(orderByCall);






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 25 at 16:59









        Aleks AndreevAleks Andreev

        5,9127 gold badges23 silver badges34 bronze badges




        5,9127 gold badges23 silver badges34 bronze badges





















            1














            I like to use an interface IBaseEntity that has an Id property of type T. That would make your query:



            void DoStuff<IBaseEntity>(...) 

            IQueryable<IBaseEntity> queryable = ... // given
            var sortedQueryable = queryable.OrderById(e=> e.Id); //extension method
            ...



            Extension Method:



            public static IQueryable<IBaseEntity<T>> OrderById<T>(this IQueryable<IBaseEntity<T>> query)

            return query.OrderBy(e => e.Id);



            Each entity would implement IBaseEntity and have something like



            public partial class MyEntity : IBaseEntity<long>

            [Required]
            public override long Id

            get return base.Id;
            set base.Id = value;




            Then in the context



            modelBuilder
            .Entity<MyEntity>()
            .ToTable("DatabaseTable", "DatabaseSchema")
            .HasKey(e => e.Id)
            .Property(e => e.Id)
            .HasColumnName("DatabasePrimaryKey")
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);


            Note: This requires some setup in the context and entities. The database can have whatever keys you want, you're mapping them individually to the property Id in the OnModelCreating method of the context.






            share|improve this answer

























            • This is OK if you know the name of the property is always going to be the same. In practice though, this is rarely the case.

              – DavidG
              Mar 25 at 16:46











            • As @DavidG says, my key fields are all named differently, i.e. CustomerId, InvoiceId etc.

              – Shaul Behr
              Mar 25 at 16:47











            • @ShaulBehr - I use the context to make the keys the same as far as entity framework is concerned, but they map to the named primary key in the database.

              – Noel
              Mar 25 at 17:03











            • Doesn't help if the property type isn't consistent. It may be int for one entity but Guid or string elsewhere.

              – DavidG
              Mar 25 at 18:13











            • @DavidG - I simplified in the answer, but what we've done is IBaseEntity<T> Where T is the type of primary key

              – Noel
              Mar 25 at 18:32















            1














            I like to use an interface IBaseEntity that has an Id property of type T. That would make your query:



            void DoStuff<IBaseEntity>(...) 

            IQueryable<IBaseEntity> queryable = ... // given
            var sortedQueryable = queryable.OrderById(e=> e.Id); //extension method
            ...



            Extension Method:



            public static IQueryable<IBaseEntity<T>> OrderById<T>(this IQueryable<IBaseEntity<T>> query)

            return query.OrderBy(e => e.Id);



            Each entity would implement IBaseEntity and have something like



            public partial class MyEntity : IBaseEntity<long>

            [Required]
            public override long Id

            get return base.Id;
            set base.Id = value;




            Then in the context



            modelBuilder
            .Entity<MyEntity>()
            .ToTable("DatabaseTable", "DatabaseSchema")
            .HasKey(e => e.Id)
            .Property(e => e.Id)
            .HasColumnName("DatabasePrimaryKey")
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);


            Note: This requires some setup in the context and entities. The database can have whatever keys you want, you're mapping them individually to the property Id in the OnModelCreating method of the context.






            share|improve this answer

























            • This is OK if you know the name of the property is always going to be the same. In practice though, this is rarely the case.

              – DavidG
              Mar 25 at 16:46











            • As @DavidG says, my key fields are all named differently, i.e. CustomerId, InvoiceId etc.

              – Shaul Behr
              Mar 25 at 16:47











            • @ShaulBehr - I use the context to make the keys the same as far as entity framework is concerned, but they map to the named primary key in the database.

              – Noel
              Mar 25 at 17:03











            • Doesn't help if the property type isn't consistent. It may be int for one entity but Guid or string elsewhere.

              – DavidG
              Mar 25 at 18:13











            • @DavidG - I simplified in the answer, but what we've done is IBaseEntity<T> Where T is the type of primary key

              – Noel
              Mar 25 at 18:32













            1












            1








            1







            I like to use an interface IBaseEntity that has an Id property of type T. That would make your query:



            void DoStuff<IBaseEntity>(...) 

            IQueryable<IBaseEntity> queryable = ... // given
            var sortedQueryable = queryable.OrderById(e=> e.Id); //extension method
            ...



            Extension Method:



            public static IQueryable<IBaseEntity<T>> OrderById<T>(this IQueryable<IBaseEntity<T>> query)

            return query.OrderBy(e => e.Id);



            Each entity would implement IBaseEntity and have something like



            public partial class MyEntity : IBaseEntity<long>

            [Required]
            public override long Id

            get return base.Id;
            set base.Id = value;




            Then in the context



            modelBuilder
            .Entity<MyEntity>()
            .ToTable("DatabaseTable", "DatabaseSchema")
            .HasKey(e => e.Id)
            .Property(e => e.Id)
            .HasColumnName("DatabasePrimaryKey")
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);


            Note: This requires some setup in the context and entities. The database can have whatever keys you want, you're mapping them individually to the property Id in the OnModelCreating method of the context.






            share|improve this answer















            I like to use an interface IBaseEntity that has an Id property of type T. That would make your query:



            void DoStuff<IBaseEntity>(...) 

            IQueryable<IBaseEntity> queryable = ... // given
            var sortedQueryable = queryable.OrderById(e=> e.Id); //extension method
            ...



            Extension Method:



            public static IQueryable<IBaseEntity<T>> OrderById<T>(this IQueryable<IBaseEntity<T>> query)

            return query.OrderBy(e => e.Id);



            Each entity would implement IBaseEntity and have something like



            public partial class MyEntity : IBaseEntity<long>

            [Required]
            public override long Id

            get return base.Id;
            set base.Id = value;




            Then in the context



            modelBuilder
            .Entity<MyEntity>()
            .ToTable("DatabaseTable", "DatabaseSchema")
            .HasKey(e => e.Id)
            .Property(e => e.Id)
            .HasColumnName("DatabasePrimaryKey")
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);


            Note: This requires some setup in the context and entities. The database can have whatever keys you want, you're mapping them individually to the property Id in the OnModelCreating method of the context.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 25 at 23:16

























            answered Mar 25 at 16:42









            NoelNoel

            50611 silver badges28 bronze badges




            50611 silver badges28 bronze badges












            • This is OK if you know the name of the property is always going to be the same. In practice though, this is rarely the case.

              – DavidG
              Mar 25 at 16:46











            • As @DavidG says, my key fields are all named differently, i.e. CustomerId, InvoiceId etc.

              – Shaul Behr
              Mar 25 at 16:47











            • @ShaulBehr - I use the context to make the keys the same as far as entity framework is concerned, but they map to the named primary key in the database.

              – Noel
              Mar 25 at 17:03











            • Doesn't help if the property type isn't consistent. It may be int for one entity but Guid or string elsewhere.

              – DavidG
              Mar 25 at 18:13











            • @DavidG - I simplified in the answer, but what we've done is IBaseEntity<T> Where T is the type of primary key

              – Noel
              Mar 25 at 18:32

















            • This is OK if you know the name of the property is always going to be the same. In practice though, this is rarely the case.

              – DavidG
              Mar 25 at 16:46











            • As @DavidG says, my key fields are all named differently, i.e. CustomerId, InvoiceId etc.

              – Shaul Behr
              Mar 25 at 16:47











            • @ShaulBehr - I use the context to make the keys the same as far as entity framework is concerned, but they map to the named primary key in the database.

              – Noel
              Mar 25 at 17:03











            • Doesn't help if the property type isn't consistent. It may be int for one entity but Guid or string elsewhere.

              – DavidG
              Mar 25 at 18:13











            • @DavidG - I simplified in the answer, but what we've done is IBaseEntity<T> Where T is the type of primary key

              – Noel
              Mar 25 at 18:32
















            This is OK if you know the name of the property is always going to be the same. In practice though, this is rarely the case.

            – DavidG
            Mar 25 at 16:46





            This is OK if you know the name of the property is always going to be the same. In practice though, this is rarely the case.

            – DavidG
            Mar 25 at 16:46













            As @DavidG says, my key fields are all named differently, i.e. CustomerId, InvoiceId etc.

            – Shaul Behr
            Mar 25 at 16:47





            As @DavidG says, my key fields are all named differently, i.e. CustomerId, InvoiceId etc.

            – Shaul Behr
            Mar 25 at 16:47













            @ShaulBehr - I use the context to make the keys the same as far as entity framework is concerned, but they map to the named primary key in the database.

            – Noel
            Mar 25 at 17:03





            @ShaulBehr - I use the context to make the keys the same as far as entity framework is concerned, but they map to the named primary key in the database.

            – Noel
            Mar 25 at 17:03













            Doesn't help if the property type isn't consistent. It may be int for one entity but Guid or string elsewhere.

            – DavidG
            Mar 25 at 18:13





            Doesn't help if the property type isn't consistent. It may be int for one entity but Guid or string elsewhere.

            – DavidG
            Mar 25 at 18:13













            @DavidG - I simplified in the answer, but what we've done is IBaseEntity<T> Where T is the type of primary key

            – Noel
            Mar 25 at 18:32





            @DavidG - I simplified in the answer, but what we've done is IBaseEntity<T> Where T is the type of primary key

            – Noel
            Mar 25 at 18:32

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55342324%2fc-sharp-expression-to-sort-generic-query-by-key-field%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

            용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

            155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해