Quelle est la bonne façon de Joindre deux tables dans ASP.NET MVC?
J'ai travaillé sur un simple Dropbox-like app, pour apprendre quelques ASP.NET MVC. Mais avant d'en arriver à une page de travail décemment je suis coincée, et il y a tellement d'infos que je ne peux pas voir la forêt pour les arbres de plus.
Ma situation:
Je veux afficher sur une page tous les fichiers dans un dossier appartenant à une certaine personne. J'ai conçu ma base de données à l'avance et ensuite généré un Code Premier modèle EF. La partie pertinente de la base de données ci-dessous. Notez que AspNetUsers
fait partie de MVC5 Identité. La liaison Identity
à mes propres tableaux, qui semble être la partie la plus difficile, car les tables appartenant à Identity
sont mis en œuvre dans IdentityModels, tandis que mes tableaux sont mis en œuvre dans TADModels.
J'ai été à la suite de divers tutoriels sur cette page, mais n'arrive pas à trouver quelque chose qui m'aide à accomplir ce dont j'ai besoin. Je suis fondamentalement juste essayer d'exécuter la requête suivante:
SELECT f.FileName, f.FileSize
FROM Files f
INNER JOIN FileTree ft ON ft.FolderID = f.FolderID
INNER JOIN AspNetUsers u ON ft.UserID = u.Id
WHERE u.id = @id AND ft.FolderPath = @path;
Selon l'un de ces tutoriels, je suis censé être en mesure de faire quelque chose le long des lignes de:
namespace TAD.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("FileTree")]
public partial class FileTree
{
[Key]
public string FolderID { get; set; }
[Required]
[StringLength(128)]
public string UserID { get; set; }
[Required]
[StringLength(255)]
public string FolderName { get; set; }
[Required]
[StringLength(255)]
public string FolderPath { get; set; }
public virtual ICollection<File> Files { get; set; }
public virtual ApplicationUser user { get; set; }
}
}
Les Fichiers de la Collection est censé trouver les fichiers associés avec le chemin d'accès, et l'utilisateur est censé trouver l'utilisateur associé avec le chemin d'accès. Mais au cours de l'Échafaudage j'ai des erreurs le long de la lignes de TAD.Models.IdentityUserRole: EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType'
. Qui, je suppose, est produit en raison de ApplicationUSer user
Cette question semble très déroutant, même pour moi. Je ne sais pas ce que je suis à la recherche pour. Les tutoriels que j'ai mentionnés présentent des situations trop simples pour mes besoins, tandis que d'autres l'info, c'est beaucoup trop avancé.
EDIT: C'est le Fichier de Modèle:
namespace TAD.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
public partial class File
{
[Key]
public string FileID { get; set; }
[Required]
[StringLength(128)]
public string UserID { get; set; }
[Required]
[StringLength(128)]
public string FolderID { get; set; }
[Required]
[StringLength(255)]
public string FileName { get; set; }
public decimal FileSize { get; set; }
public bool IsPublic { get; set; }
public virtual ApplicationUser user { get; set; }
public virtual FileTree folder { get; set; }
}
}
File
modèle? Vous pouvez simplement le faire manuellement via LINQAjouter mon Fichier de classe. L'annotation de la Clef a été suggéré dans l'une des réponses ci-dessous, aucune idée si j'ai réellement besoin.
Vous pouvez hériter de l'Identité des Modèles facilement, ajouter une de vos propriétés! Cela peut vous aider un peu:
public class MyUser : IdentityUser {}
OriginalL'auteur Simon Verbeke | 2014-11-10
Vous devez vous connecter pour publier un commentaire.
Vous n'êtes pas seul. Données de la modélisation des masques tellement les rumeurs sur qui il peut être difficile de déterminer ce qui est bien et mal.
Il n'y a rien de mal avec l'utilisation de LINQ jointure interne dans le sens où il fonctionne, et il obtient ce dont vous avez besoin.
Cependant, l'ajout d'ICollection pour le modèle de données pour FileTree décrit une relation stable qui peut être observé lors de la lecture du code, et utilisé chaque fois que vous en avez envie (ce qui sera probablement souvent, ils sont si étroitement liés). c'est à dire non seulement Il fournit la même fonctionnalité que la jointure, mais il explique la relation à d'autres programmeurs sans avoir besoin de commentaires ou de la lecture des exemples de code.
À l'utilisation de ces types de relations, la plupart des Mappings Objet Relationnel (Entity Framework et NHibernate deux exemples de l'ORM) exiger que les modèles de spécifier une clé primaire pour le raccordement de la clé étrangère entre la table enfant dans la collecte et la table parent qui a la collection.
Donc, longue histoire courte, l'utilisation ICollection, mais ensuite également spécifier une clé primaire sur votre modèle de Fichier.
Désolé, oui, vous aurez besoin de le faire. Si vous vous demandez pourquoi, c'est parce que la plupart des ORM mettre en œuvre un certain niveau de mise en cache des objets pour empêcher de frapper à plusieurs reprises de la base de données. La seule façon dont ils peuvent raisonnablement déterminer si un objet a déjà été chargé consiste à vérifier par Clé.
OriginalL'auteur Steve Lillis
pourquoi voulez-vous rejoindre
AspNetUsers
vous n'êtes pas en sélectionnant les données à partir deAspNetUsers
c'est juste un supplément de rejoindre.vous avez juste besoin de cette
Votre EF requête LINQ va être quelque chose comme"
Avez-vous modifier IdentityUserRole? Je doit avoir une clé par défaut formulaire ASPNET d'identité et au cours de l'Échafaudage-vous dire lorsque vous générez une vue pour un modèle? Si donc le modèle qui êtes-vous essayer de se lier à la vue?
Je n'ai pas modifier quoi que ce soit lié à l'Identité. Il s'agit d'une implémentation du modèle dans le cadre de mon projet, mais qui a été générée par le projet de l'échantillon (qui génère chaque fois que vous créez un nouveau projet). Un échafaudage est lorsque vous cliquez droit sur les Contrôleurs > Ajouter > Nouvelle Échafaudée Élément. Cela génère un contrôleur et la vue. Le modèle que je suis en train de bind est FileTree, qui a des liens vers des Fichiers et IdentityUser.
Pouvez-vous essayer de créer la vue manuellement. au lieu de Échafaudée
OriginalL'auteur HaBo
Pour l'Identité des Choses que vous pouvez faire:
Donc, ici, vous pouvez voir que j'ai fait tous mes Modèles d'Identité ont
Guid
comme une clé primaire de type. Vous pouvez facilement changer cela pourint
, et je crois que c'est le chemin à parcourir!Si vous avez à faire compliqué jointures, vous devez laisser EF hors de lui, car il est tout simplement un ORM. Il ne peut pas remplacer SQL. Vous pouvez toutefois créer une belle jointure SQL dans le code et ont EF exécuter cette requête!
Je vous suggère de regarder cette première peut-être?
Évidemment de ne pas concaténer des chaînes de caractères avec la
+
, ils sont immuables.Donc permet de faire votre requête:
Si vous ne voulez pas aller dans cette voie. Le LINQ je suppose pourrait aller quelque chose comme ceci:
Donc dans
fileTrees
une liste d'objets anonymes tenue d'uneFileTree
entité et une liste deFile
entités. Basé sur l'actuel modèle.OriginalL'auteur Callum Linington
Tout en ajoutant ne pas sélectionner Contexte DB classe dans le Modèle de Vue qui permettra de fixer le "type d'entité n'a pas de clé définie erreurs".
Pour de plus amples informations, veuillez visiter:https://www.youtube.com/watch?v=T2R8tA80ZuE**
OriginalL'auteur K. Jana