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
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
|
show 3 more comments
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
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 toSQLsuch asLinq To SQLor 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
|
show 3 more comments
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
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
c# linq linq-expressions
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 toSQLsuch asLinq To SQLor 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
|
show 3 more comments
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 toSQLsuch asLinq To SQLor 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
|
show 3 more comments
3 Answers
3
active
oldest
votes
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 );
Can't we just build theExpression<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 ofTPropahead of time. I'm assuming we don't
– DavidG
Mar 25 at 16:50
1
You're right. But sinceDoStuff<T>()does define a generic parameter than can be resolved asTEntity, there's a chancekeyFieldpoints to a property of constant type that can be resolved asTProp. Anyway, great answer.
– haim770
Mar 25 at 17:01
@haim770 I was assumingkeyFieldis 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
|
show 1 more comment
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);
add a comment |
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.
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,InvoiceIdetc.
– 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 beintfor one entity butGuidorstringelsewhere.
– 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
|
show 2 more comments
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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 );
Can't we just build theExpression<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 ofTPropahead of time. I'm assuming we don't
– DavidG
Mar 25 at 16:50
1
You're right. But sinceDoStuff<T>()does define a generic parameter than can be resolved asTEntity, there's a chancekeyFieldpoints to a property of constant type that can be resolved asTProp. Anyway, great answer.
– haim770
Mar 25 at 17:01
@haim770 I was assumingkeyFieldis 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
|
show 1 more comment
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 );
Can't we just build theExpression<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 ofTPropahead of time. I'm assuming we don't
– DavidG
Mar 25 at 16:50
1
You're right. But sinceDoStuff<T>()does define a generic parameter than can be resolved asTEntity, there's a chancekeyFieldpoints to a property of constant type that can be resolved asTProp. Anyway, great answer.
– haim770
Mar 25 at 17:01
@haim770 I was assumingkeyFieldis 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
|
show 1 more comment
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 );
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 );
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 theExpression<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 ofTPropahead of time. I'm assuming we don't
– DavidG
Mar 25 at 16:50
1
You're right. But sinceDoStuff<T>()does define a generic parameter than can be resolved asTEntity, there's a chancekeyFieldpoints to a property of constant type that can be resolved asTProp. Anyway, great answer.
– haim770
Mar 25 at 17:01
@haim770 I was assumingkeyFieldis 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
|
show 1 more comment
Can't we just build theExpression<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 ofTPropahead of time. I'm assuming we don't
– DavidG
Mar 25 at 16:50
1
You're right. But sinceDoStuff<T>()does define a generic parameter than can be resolved asTEntity, there's a chancekeyFieldpoints to a property of constant type that can be resolved asTProp. Anyway, great answer.
– haim770
Mar 25 at 17:01
@haim770 I was assumingkeyFieldis 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
|
show 1 more comment
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);
add a comment |
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);
add a comment |
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);
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);
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
add a comment |
add a comment |
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.
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,InvoiceIdetc.
– 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 beintfor one entity butGuidorstringelsewhere.
– 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
|
show 2 more comments
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.
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,InvoiceIdetc.
– 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 beintfor one entity butGuidorstringelsewhere.
– 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
|
show 2 more comments
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.
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.
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,InvoiceIdetc.
– 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 beintfor one entity butGuidorstringelsewhere.
– 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
|
show 2 more comments
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,InvoiceIdetc.
– 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 beintfor one entity butGuidorstringelsewhere.
– 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
|
show 2 more comments
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
SQLsuch asLinq To SQLor 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