views:

560

answers:

2

Hi folks,

i've got the following linq2sql query, and i'm setting the result to a POCO. One of my POCO properties is an enumeration.

public IQueryable<Models.Achievement> GetAchievements()
{
    return from a in _sqlDatabase.Achievements
        select new Models.Achievement
            {
                // Note: ToEnum is an extension method that converts an int -> the enum.
                AchievementType = a.AchievementTypeId.ToEnum<Models.AchievementType>(),
                DateTimeCreated = a.DateTimeCreated,
                UserId = a.UserId
            };
}

When i run the query, i get the following error.

System.NotSupportedException: Method 'Models.AchievementType 
    ToEnum[AchievementType](int)' has no supported translation to SQL.

hmm. is there a way i can be tricky enough to make the result int get converted to my custom enum?

+3  A: 

You can actually use enums directly in LINQ-to-SQL (but not Entity Framework); just change the type of the property (in the dbml/designer) to the fully qualified enum type, and it will do the cast for you. You might want to call it AchievementType, of course - and this assumes a straight (cast) translation.

If this doesn't fit your scenario, you'll probably have to select it as an integer, and then do the final cast in LINQ-to-Objects (via AsEnumerable()). You could also try a straight cast (assuming this is sufficient) instead of your generic extension method:

select new {..., AchievementType = (AchievementType) foo.Bar, ...}

Not that if the Models.Achievement type is defined in the dbml, you can't create it this way - you have to simple select it. But if this is not part of the db-model then it is fine. Here's a related example for mapping strings to enums in LINQ-to-SQL.

If neither of these suits, the other approach is to declare the enum property as a shim in a partial class. I gave an example of this here (for EF, but it works the same), but note that if you do this, you can't use the enum property in Where clauses etc, since it isn't mapped in the model.

Marc Gravell
Wow - awesome! i removed my AchievementType L2S class and renamed the AchievementTypeId field to AchivementType. Then set the property type to my FQDN enum struct. MS tested -> worked! awesome! not only does it work, but my designer is cleaner with the lookup classes now removed! awesomesauce!
Pure.Krome
A: 

Maybe you could try something like this in you Models.Achievement declaration:

  AchievementType achievementType{
    get
      {
         return this.AchievementTypeId.ToEnum<Models.AchievementType>();
      }
      set
      {
        this.AchievementTypeId = (int)value;
      }
    }
Sorskoot