je un suivant SQL Server schéma de base de données 2005:projection entité Nullable dans Entity Framework
CREATE TABLE Messages (
MessageID int,
Subject varchar(500),
Text varchar(max) NULL,
UserID NULL
)
La colonne "UserID" - qui peut être nulle - est une clé étrangère et des liens vers la table
CREATE TABLE Users (
UserID int,
...
)
maintenant, j'ai plusieurs classes POCO avec des noms des messages, etc. utilisateur que j'utilise dans la requête suivante:
public IList<Message> GetMessages(...) {
var q = (from m in dataContext.Messages.Include("User")
where ...
select m); // could call ToList(), but...
return (from m in q
select new Message {
ID = m.MessageID,
User = new User {
ID = m.User.UserID,
FirstName = m.User.FirstName,
...
}
}).ToList();
}
Notez maintenant que je conseille le framework d'entité - en utilisant Include ("Users") - pour charger un utilisateur associé à un message, le cas échéant. Notez également que je n'appelle pas ToList() après la première instruction LINQ. Ce faisant, seules les colonnes spécifiées dans la liste de projection - dans ce cas, MessageID, UserID, FirstName - seront renvoyées à partir de la base de données.
Voici le problème - dès que Entity Framework rencontre un message avec UserID == NULL, il lève une exception, disant qu'il ne pouvait pas convertir en Int32 parce que la valeur DB est NULL.
Si je change les deux dernières lignes
return (from m in q
select new Message {
ID = m.MessageID,
User = m.User == null ? null : new User {
ID = m.User.UserID,
...
}
}).ToList()
puis une exécution NotSupportedException est jeté dire qu'il ne peut pas créer un type d'utilisateur constante et primitives seulement comme int, string, guid sont pris en charge .
Quelqu'un a-t-il une idée de la façon de le gérer en plus de matérialiser les résultats juste après la première instruction et d'utiliser ensuite la projection en mémoire? Merci.
Le type de message que vous projetez diffère-t-il du type de m? Pourquoi projetez-vous du tout? –
Pourquoi construisez-vous de nouveaux objets Message et Utilisateur plutôt que d'utiliser ceux que vous avez récupérés à partir de q? Je pense que vous n'utilisez pas bien le cadre. –
@ DavidB: Message est un POCO, m est une classe Entity. @ Orion Adrian: Eh bien, je veux être en mesure de mettre en cache les résultats de la requête plus tard. Avec les objets d'entité, vous devez les détacher manuellement (y compris tous les objets dépendants, par ex. Utilisateur dans ce cas, ce qui est beaucoup trop de tracas (LINQ2SQL a le même problème). –