2017-10-14 2 views
1

J'utilise le code Entity Framework d'abord et a couru dans un petit problème.classe d'accès de GUID

J'ai deux tables en tant que tels:

User 
+--------+-----------+ 
| id | name | 
+--------+-----------+ 
| def789 | Bob Smith | 
+--------+-----------+ 

Actions 
+--------+--------------+-------------+ 
| id | grantedTo_id | details | 
+--------+--------------+-------------+ 
| abc123 | def789  | some detail | 
+--------+--------------+-------------+ 

faire semblant les 3 champs d'identification sont GUIDs à ​​cet effet.

Mes cours ressemblent à:

User 
{ 
public Guid id {get; set;} 
public string name {get; set;} 
} 

Actions 
{ 
public Guid id {get; set;} 
public User grantedTo {get; set;} 
public string details {get; set;} 
} 

Mon problème est que, puisque la classe définit grantedTo en tant que type utilisateur, rien n'est retourné en elle la base de données (car il est de type Guid).

Ainsi, par exemple, si je fais quelque chose de simple comme:

var action = db.Action.ToList() 
foreach (var a in db.Action) 
{ 
var user = a.GrantedTo 
} 

Ensuite, l'utilisateur contient null.

Comment puis-je obtenir l'utilisateur référencé par le Id?

Ils ont été fait le code d'abord, je l'ai apporté aucune modification à leur disposition. Y a-t-il un descripteur ou quelque chose que je devrais utiliser? Je pensais que je pouvais faire quelque chose comme:

var action = db.Action.ToList() 
foreach (var a in action) 
{ 
var user = db.Users.Find(...???) 
} 

Mais je n'ai pas la moindre idée de quoi mettre là-dedans depuis le GUID ne revient pas non plus.

+2

Votre classe 'Action' devrait avoir' public virtual User grantedTo {get; set;} 'et' public Guid UserId {get; ensemble; } 'pour créer une propriété de navigation - reportez-vous à [Entity Framework Relationships and Navigation Properties] (https://msdn.microsoft.com/fr-fr/library/jj713564 (v = vs.113) .aspx) –

+0

@StephenMuecke OP déjà avoir un utilisateur public grantTo {get; set;} ', ce qui est suffisant. La propriété FK «virtuelle» ou explicite n'est pas * obligatoire *. –

+1

Puisque votre propriété 'grantedTo' n'est pas' virtual', elle ne peut pas être chargée paresseusement et vous devez la charger en utilisant un chargement rapide ou explicite. Par exemple,. 'var action = db.Action.Include (a => a.grantedTo) .ToList();' va peupler la propriété 'grantedTo' des actions de la liste. –

Répondre

3

Comme expliqué dans la rubrique documentation Entity Framework Loading Related Entities, EF prend en charge trois façons de charger les données relatives - chargement désireux, chargement paresseux et chargement explicite.

Étant donné que la propriété grantedTo n'est pas marquée virtual, elle n'est pas éligible pour le chargement différé, qui est le seul moyen des trois dans lesquels EF charge automatiquement les données associées. Alors que dans les deux autres EF ne le fait que par votre demande explicite, qui de l'autre côté vous donne un meilleur contrôle.

Par exemple, en utilisant la méthode Include (chargement impatient)

var action = db.Action.Include(a => a.grantedTo).ToList(); 

va peupler la propriété grantedTo des actions dans la liste.

Un autre avantage de cette manière est qu'elle est compatible avec EF Core qui ne supporte pas (actuellement) le chargement paresseux.

1

Si vous utilisez le code d'abord, vous devez changer votre définition d'action pour:

public class Action 
{ 
    [Key] 
    public Guid ActionId { get; set; } 
    // ... 
    public Guid GrantedToId { get; set; } 
    [ForeignKey("GrantedToId")] 
    public virtual User GrantedTo { get; set; } 
    // ... 
} 

Si vous utilisez EF6 vous pouvez utiliser EntityTypeConfiguration pour configurer les relations sans avoir des propriétés FK définies:

public class ActionConfiguration : EntityTypeConfiguration<Action> 
{ 
    public ActionConfiguration() 
    { 
    ToTable("Actions"); 
    HasKey(x => x.ActionId); 

    HasRequired(x => x.GrantedTo) 
     .WithMany() 
     .Map(x => x.MapKey("GrantedToId")) 
     .WillCascadeOnDelete(false); 
    } 
} 

Ma préférence avec EF est d'utiliser des configurations de type d'entité que je préfère schéma premier développement et il me donne plus de contrôle sur la façon dont la cartographie sera mis en place. Je n'aime pas avoir à la fois les propriétés de navigation et les propriétés FK puisque vous avez des paramètres publics sur les deux. Cela laisse toutes sortes de scénarios laids où vous pourriez avoir un FK, mais aucune référence chargé ... Ou lors du changement de référence ce qui se passe si le champ FK ne correspond pas, ou vous définissez le FK sans mettre à jour la référence.