2008-12-15 5 views
1

J'ai la requête linq2sql suivante, et je mets le résultat à un POCO. Une de mes propriétés POCO est une énumération.Comment Linq2Sql peut-il créer une énumération dans la clause select?

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 
      }; 
} 

Lorsque j'exécute la requête, j'obtiens l'erreur suivante.

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

hmm. y at-il un moyen que je peux être assez difficile pour que le résultat int soit converti à mon énum personnalisé?

Répondre

3

Vous pouvez réellement utiliser des énumérations directement dans LINQ-to-SQL (mais pas dans Entity Framework); changez juste le type de la propriété (dans le dbml/concepteur) au type enum entièrement qualifié, et il fera le cast pour vous. Vous pourriez vouloir l'appeler AchievementType, bien sûr - et cela suppose une traduction directe (cast).

Si cela ne correspond pas à votre scénario, vous devrez probablement le sélectionner en tant qu'entier, puis effectuer la distribution finale dans LINQ-to-Objects (via AsEnumerable()). Vous pouvez également essayer un casting droit (en supposant que cela suffit) à la place de votre méthode d'extension générique:

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

Non pas que si le type Models.Achievement est défini dans le dbml, vous ne pouvez pas créer de cette façon - vous avez pour le sélectionner simplement. Mais si cela ne fait pas partie du modèle db, alors ça va. Here est un exemple associé pour mapper des chaînes à enums dans LINQ-to-SQL.

Si aucune de ces combinaisons ne convient, l'autre approche consiste à déclarer la propriété enum en tant que shim dans une classe partielle. J'ai donné un exemple de ceci here (pour EF, mais cela fonctionne de la même manière), mais notez que si vous faites cela, vous ne pouvez pas utiliser la propriété enum dans Where clauses etc, car il n'est pas mappé dans le modèle.

+0

Wow - génial! J'ai supprimé ma classe L2S AchievementType et renommé le champ AchievementTypeId en AchivementType. Définissez ensuite le type de propriété sur ma structure enum FQDN. MS testé -> travaillé! impressionnant! non seulement cela fonctionne, mais mon concepteur est plus propre avec les classes de recherche maintenant supprimées! sauce extraordinnaire! –

0

Peut-être que vous pourriez essayer quelque chose comme ça en vous déclaration Models.Achievement:

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