2009-08-10 8 views
2

J'essaye d'obtenir le chargement impatient de travailler avec Subsonic, et il a rendu null pour moi.Linq imbriqué sélectionnez nouveau ne fonctionne pas

Dans la méthode ci-dessous, j'essaie d'hydrater un modèle de domaine (UserModel) qui contient un autre modèle de domaine (CompanyModel). Cependant, avec le code ci-dessous, UserModel.Company est toujours null.

Qu'est-ce qui me manque ici? Toute aide serait appréciée.

public IList<UserModel> GetUsers() 
{    
    return (from u in SubsonicSqlServer.Users.All() 
      select new UserModel 
         { 
          UserId= u.UserId, 
          Company = (from c in u.Companies 
            select new CompanyModel 
               { 
                CompanyId = c.CompanyId, 
                CompanyName = c.CompanyName 
               }).SingleOrDefault(), 
          FirstName = u.FirstName, 
          LastName = u.LastName, 
          BirthDate = u.BirthDate 
         }).ToList(); 

} 

Mise à jour (08/11/09):

Plus avec le toying autour de code, je trouve que la mise en COMPANYID dans l'exemple suivant ne fonctionne pas non plus. J'ai d'abord pensé que c'était un problème avec Subsonic, mais si le code ci-dessous ne fonctionne pas, je suppose que cela a quelque chose à voir avec ma déclaration Linq. Des idées?

public IList<UserModel> GetUsers() 
{    
    return (from u in SubsonicSqlServer.Users.All() 
      select new UserModel 
         { 
          UserId= u.UserId,        
          CompanyId = Guid.NewGuid(), 
          FirstName = u.FirstName, 
          LastName = u.LastName, 
          BirthDate = u.BirthDate 
         }).ToList(); 

} 

Mise à jour (11/17/2009):

n'a pas encore trouvé une solution. Mais nous passons à nHibernate (pas à cause de ce problème).

+0

Selon ce fil, il y a des problèmes avec la projection (sélectionnant un type non-SubSonic): http://groups.google.com/group/subsonicproject/browse_thread/thread/2b569539b7f67a34?hl=fr&pli=1 Cela peut être lié à cela. –

+0

quelle version subsonique que vous utilisez? – Funky81

+0

@ Funky812: Subsonic version 3.0.0.3 – Jason

Répondre

0

Deux choses

  1. vous retournez un List<UserModel> lorsque la ligne de signature de votre méthode dit IList<User>-t UserModel Hériter de User?

  2. Ai-je manqué quelque chose, d'où vient e?

FirstName = e.FirstName, LastName = e.LastName, BirthDate = e.BirthDate Blockquote

+0

wawa, En ce qui concerne 1) Mon mauvais, la signature de retour aurait dû être IList . Je vais mettre à jour le code dans la question originale 2) Encore une fois, mon mauvais, e, aurait dû être vous. Ce que j'ai fait, c'est que j'ai copié le code source et le transformer en quelque chose que je peux partager. Mais il n'a pas été fait assez soigneusement comme il semble. Merci de l'avoir attrapé. – Jason

2

"UserModel.Company est toujours nulle."

étant donné que vous définissez ceci avec une expression qui se termine par .SingleOrDefault(), je vais suggérer que la requête ne renvoie pas un seul élément. Commencez à enquêter là-bas. Si vous attendez exactement un élément dans u.Companies, passez à .Single() et forcez un échec anticipé.

Vous pouvez faire le .Single() avant de créer le nouvel objet CompanyModel, je pense. En ce qui concerne le style, j'aime la syntaxe de compréhension de la requête ("from x in y select") mais je trouve cela bizarre quand on la combine avec la syntaxe traditionnelle de la notation par points. C'est juste difficile à lire. (LINQ - Fluent and Query Expression - Is there any benefit(s) of one over other?).

Envisagez d'utiliser let dans la compréhension de la requête pour le rendre plus clair.

De plus, comme une requête renvoie déjà un IEnumerable<T> et que l'appel ToList() force tous les éléments à réaliser, je modifierais ma méthode pour renvoyer IEnumerable<T> si possible.

Ainsi, dans votre cas, je serais factoriser le premier à dire:

public IEnumerable<User> GetUsers() 
{ 
    return from u in SubsonicSqlServer.Users.All() 
     let c = u.Companies.Single() 
     select new UserModel 
     { 
      UserId = u.UserId, 
      Company = new CompanyModel 
      { 
       CompanyId = c.CompanyId, 
       CompanyName = c.CompanyName 
      }, 
      FirstName = e.FirstName, 
      LastName = e.LastName, 
      BirthDate = e.BirthDate 
     }; 
} 

S'il est logique dans votre modèle objet, vous pouvez modifier User d'avoir un constructeur qui prend tout type u est, et il est encore plus simple:

return from u in SubsonicSqlServer.Users.All() 
    select new UserModel (u); 

ou même

return SubsonicSqlServer.Users.All().Select(u => new UserModel (u)); 
+0

Jay, j'ai implémenté votre suggestion et maintenant je reçois une erreur Subsonic: "Référence à une colonne indéfinie". Je vais continuer à résoudre les problèmes. – Jason