ByteArtisan ByteArtisan - 3 months ago 8
C# Question

Seamless way to store and retrieve enums from a string field using EF Model

I have several enums, that represent states, and all correspond to string fields on the EF model.
All enums values are chosen so they can be easily represented as chars, so they are set like this:

public enum eStateCode
{
Running = 'R',
Terminated = 'T',
Cancelled = 'C',
}


This way database field can be a char[1] type, capable of storing meaning codes, instead a abstract numeric field. This approach works seamless using Linq to SQL, because char SQL columns are mapped to char fields, but not using EF.

Using EF, when i try to use it on a lambda expression like this

s => s.WFStateCode == ((char)ClassX.eStateCode.Running).ToString())


i get the


LINQ to Entities does not recognize the method


error, meaning that
((char)ClassX.eStateCode.Running).ToString()
was sent to SQL.

I can circumvent the problem by putting put
((char)ClassX.eStateCode.Running).ToString()
in a variable but makes the code much more verbose.
I read several posts but none say how I can force EF to resolve the part of expression on the client side.

It is possible to define a method that can be used in a lambda expression as a literal, so it will not be sent to SQL?

Answer

It is possible to define a method that can be used in a lambda expression as a literal, so it will not be sent to SQL?

No, that's not possible.

But I could suggest you another approach that would keep your current design and at the same time will allow you to use an even more concise syntax than

s => s.WFStateCode == ((char)ClassX.eStateCode.Running).ToString())

Right after each enum declare another static class with static readonly fields containing the string codes of the enum members. Something like this:

public enum eStateCode
{
    Running = 'R',
    Terminated = 'T',
    Cancelled = 'C',
}

public static class DbStateCode
{
    public static readonly string Running = ((char)eStateCode.Running).ToString();
    public static readonly string Terminated = ((char)eStateCode.Terminated).ToString();
    public static readonly string Cancelled = ((char)eStateCode.Cancelled).ToString();
}

Yes, that requires some additional effort. But it's one time effort and once you have just several enums like this I think it's worth enough. Because then you can use simply:

s => s.WFStateCode == ClassX.DbStateCode.Running
Comments