2009-09-18 6 views
3

Je suis le prototypage de ma première application MVC, c'est un forum simple. J'ai fait une partie du modèle de domaine et j'essaie de comprendre comment faire quelque chose qui est assez basique dans SQL seul, mais je ne peux pas le comprendre dans mon application. Voici mes entités:MVC - Linq - Remplir la liste <T> avec des enregistrements dans une autre table

[Table(Name="Users")] 
public class User 
{ 
    [Column(IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.OnInsert)] 
    public int Id { get; set; } 

    [Column] public string Username { get; set; } 
    [Column] public string Password { get; set; } 
    [Column] public string PasswordHash { get; set; } 
    [Column] public string PasswordSalt { get; set; } 
    [Column] public string FirstName { get; set; } 
    [Column] public string LastName { get; set; } 
    public List<Forum> AllowedForums { get; set; } 
    [Column] public DateTime LastLogin { get; set; } 
    [Column] public DateTime MemberSince { get; set; } 
} 

[Table(Name="Forums")] 
public class Forum 
{ 
    [Column(IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.OnInsert)] 
    public int Id { get; set; } 
    [Column] public int ParentId { get; set; } 
    [Column] public string Title { get; set; } 
    [Column] public string Description { get; set; } 
    [Column] public bool IsGlobal { get; set; } 
    [Column] public int DisplayOrder { get; set; } 
} 

J'ai aussi une table de liaison appelé AllowedForums qui ressemble à:

userid forumid 
    1  4 

Afin de sélectionner les forums que l'utilisateur est autorisé à voir et des forums où isGlobal == vrai que je ferais ceci dans SQL:

SELECT * FROM Forums 
LEFT OUTER JOIN AllowedForums ON Forums.id = AllowedForums.Forumid 
WHERE AllowedForums.Userid = 1 
OR Forums.IsGlobal = 1 

Comment dois-je remplir le

public List<Forum> AllowedForums 

champ utilisant C#/Linq à SQL?

Est-ce que AllowedForum doit être un objet de valeur avec son propre mappage de table? Cela semble exagéré mais je pourrais facilement y participer. J'ai regardé brièvement EntitySet mais l'exemple simple que j'ai vu ne semblait pas convenir. Il semble qu'il devrait y avoir un moyen élégant d'obtenir une collection d'objets Forum pour chaque utilisateur, mais je ne peux pas en trouver. BTW, je suis nouveau à C# & OO. Je devrais également mentionner que puisque ce sont les premières étapes de l'application, je suis ouvert à changer la structure/les relations des entités ou des tables s'il y a une meilleure approche que je ne vois pas.

Répondre

3

Vous devriez avoir une autre classe d'entité (devrait probablement être interne) qui reflète votre table AllowedForums dans la base de données. Maintenant, je suppose que votre table utilisateur et votre table Forums ont tous les deux des relations PK/FK avec cette table AllowedForums. Par conséquent, il doit y avoir une propriété interne sur la classe User qui ressemble à ceci:

internal EntitySet<AllowedForums> AllowedForumsRelationships 
{ 
    get;set; 
} 

Ou quelque chose comme ça. Cela devrait être sur la classe Utilisateur et Forums. Votre classe AllowedForums aura deux propriétés dessus. Un pour l'utilisateur et un pour le forum. (Si vous utilisez le concepteur LINQ to SQL, tout cela se fera automatiquement pour vous).

Une fois que vous avez, si vous voulez obtenir tous les AllowedForums pour un utilisateur que vous pouvez faire quelque chose comme ceci:

public IList<Forum> AllowedForums 
    { 
     get 
     { 
      var result = new List<Forum>(); 
      foreach(var relationShip in this.AllowedForumsRelationships) 
      { 
      result.Add(relationShip.Forum); 
      return result; 
      } 
     } 
    } 

Ceci est un code rugueux je viens cogné, et je ne suis pas sûr c'est 100% précis, mais je pense que vous aurez l'idée. Fondamentalement, vous avez affaire à une relation de plusieurs à plusieurs qui est toujours une douleur.

EDIT: Je viens sali avec cette idée avec la base de données Northwind avec ces tableaux:

Commandes OrderDetails Produits

Il y a plusieurs à plusieurs là: Une commande peut avoir plusieurs produits, et un produit peut appartenir à plusieurs ordres.Maintenant, supposons que vous voulez obtenir tous les produits pour une commande:

public partial class Order 
{ 
     public IList<Product> Products 
     { 
      get 
      { 
       var list = new List<Product>(); 
       foreach (var item in this.Order_Details) 
       { 
        list.Add(item.Product); 
       } 
       return list; 
      } 
     } 
} 

Cela fonctionne, il devrait donc travailler dans le scénario que vous parlez aussi bien.

+0

Ne serait-ce pas pour chaque sortie lors de sa première itération? –

+0

quelque chose comme get {return from r dans AllowerForumsRelationship select r.Forum; } –

+0

Je pense que j'en ai assez pour essayer ça. Je vais vous laisser savoir comment ça se passe. – Dzejms

0

Quelque chose comme:

var AllowedForums = from f in ForumsTable 
        join af in AllowedForumsTable on f.Id equals af.forumid into temp 
        from aft in temp.DefaultIfEmpty() 
        where (f.IsGlobal == 1 || aft.userid == 1) 
        select f; 
Questions connexes