Linq To SQL OrderBy, Problem Using Enums

I am having some problems using the OrderBy extension method in a LINQ query when it works with an enum type. I created a regular DataContext using visual studio, just dragging and dropping everything onto the constructor. Then I created separate entity models that are just POCO, and I used the repository template to retrieve data from my database and map it to my own entity models (or rather, I have a repository template that is created and IQueryable that will do all this) .

Everything works fine, except when I try to apply OrderBy (outside the repository) for the property that I mapped from short / smallint to an enumeration.

Here are the relevant code bits:

public class Campaign { public long Id { get; set; } public string Name { get; set; } .... public CampaignStatus Status { get; set; } ... } public enum CampaignStatus : short { Active, Inactive, Todo, Hidden } public class SqlCampaignRepository : ICampaignRepository { ... public IQueryable<Campaign> Campaigns() { DataContext db = new DataContext(); return from c in db.Campaigns select new Campaign { Id = c.Id, Name = c.Name, ... Status = (CampaignStatus)c.Status, ... }; } } 

And then elsewhere

 SqlCampaignRepository rep = new SqlCampaignRepository(); var query = rep.Campaigns().OrderBy(c => c.Status); 

This raises the following exception: System.ArgumentException was not handled by user code Message = “Argument value” was incorrect. Expected “IQMedia.Models.CampaignType.” Actual “System.Int16.” Source = “System.Data.Linq” Trace stack : ved System.Data.Linq.SqlClient.SqlOrderExpression.set_Expression (SqlExpression value) ved System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect (select SqlSelect) ved System.Data.Linq.SqlClient.SqlVisitor.is ) ved System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitIncludeScope (SqlIncludeScope area) ...

(sorry for Danish there, ved = by / at).

I tried typecasting Status in short in the orderBy expression, but that doesn’t help, just as if I also applied it to the actual type of the enum.

Any help correcting this is greatly appreciated!

+6
enums c # linq-to-sql
source share
3 answers

Can you specify the CampaignStatus type directly in your DataContext through the constructor? Thus, the value is automatically mapped to enum .

+3
source share

What is the relationship between the Campaign class and Campaigns ? If Campaigns returns a collection of Campaign objects, note that you cannot normally select new displayed object.

I wonder if this would work better if you did OrderBy before choosing?

One final trick might be to create a fake composite [Function] using the trivial TSQL. For example, ABS might be enough. i.e. something like (in context):

  [Function(Name="ABS", IsComposable=true)] public int Abs(int value) { // to prove not used by our C# code... throw new NotImplementedException(); } 

Then try:

  .OrderBy(x => ctx.Abs(x.Status)) 

I have not tested the above, but I can give it later ... it works for some other similar cases.

It’s worth taking a picture ...

+1
source share

My DataContext has its own entity class called Campaign (of course, living in a different namespace). In addition, the status column is saved as a small value in the database, and the LINQ Entity namespace is of the type specified as short (System.Int16).

Orderby DOES works if I use it in a query in my repository - all this is part of the bigger thing, although the whole idea is to NOT use a repository of any kind, filtering or something like that, but just map the classes of the base objects data with my own. This example right there is obviously a little pointless, in which it is pretty much a direct comparison, but in some cases I also added localization to it.

And I forgot to add - the exception obviously does not occur until I try to execute the request (i.e. by calling ToList or listing by collection).

In a larger picture, this method is used by the service class, which then has to add filtering, sorting and all that - and all this, of course, should separate things a bit, but also allow easy transition to another database or another OR / M, later if it will be a desire.

And I did not see this last bit until I answered - I did not have experience using the Function attribute, but I will not have access to the datacontext in the class where I should apply sorting.

0
source share

All Articles