27 votes

Définition d'une clé étrangère à null lors de l'utilisation d'entity framework code first

Je suis à l'aide de la première base de données de mise en œuvre de l'Entity Framework Code First que la couche de données pour un projet, mais j'ai couru dans un problème.

J'ai besoin d'être en mesure de définir une clé étrangère à null pour supprimer une association dans la base de données.

J'ai 2 objets. L'un est appelé Projet.

public class Project
{
    public int ProjectId {get; set;}
    public Employee Employee {get;set;}
}

public class Employee
{
    public int EmployeeId {get; set;}
    public string EmployeeName {get;set;}
}

Cela correspond à ce que j'ai dans la Base de données:

CREATE TABLE Project(
    ProjectId int IDENTITY(1,1) NOT NULL,
    EmployeeId int NULL
)

CREATE TABLE Project(
    EmployeeId int IDENTITY(1,1) NOT NULL,
    EmployeeName varchar(100) NULL
)

Je peux affecter un Employé à un projet. Cependant, je veux être en mesure de supprimer un employé d'un projet et d'avoir le champ Employé nulle. Dans mon UI ce sera indiqué comme "Non Employés Affectés".

Cependant, à court d'une requête sql, je n'arrive pas à trouver un moyen de le faire dans l'entity framework 4.1.

J'ai essayé:

public void RemoveEmployeeFromProject(int projectId)
{
    var project = Context.Projects.FirstOrDefault(x => x.ProjectId == projectId);
    project.Employee = null;
    Context.SaveChanges();
}

Mais ce n'est pas faire n'importe quoi.

Quelqu'un aurait-il des idées?

48voto

David Ruttka Points 8105

Je pense que le problème est que dans la mesure où le contexte est concerné, vous n'avez pas fait quelque chose de changé.

Vous pouvez utiliser le chargement paresseux approche déjà suggéré en utilisant virtual, mais puisque vous n'avez pas demandé à ce que l'Employé d'être encore chargé, il est toujours null. Vous pouvez essayer ceci:

var forceLoad = project.Employee;
project.Employee = null; // Now EF knows something has changed
Context.SaveChanges();

Sinon, explicitement inclure dans votre demande initiale:

var project = Context.Projects.Include(x => x.Employee).FirstOrDefault(x => x.ProjectId == projectId);
project.Employee = null;
Context.SaveChanges();

Sur une note de côté, FirstOrDefault sera de retour null si pas d' Project correspond à l'id donné. Si vous savez que le projet existe, vous pouvez simplement utiliser First. Vous pourriez même utiliser Single qui affirment qu'il n'y a qu'un seul projet. Si vous continuez à utiliser FirstOrDefault, je vous recommande de vérifier pour null avant de travailler avec project.

4voto

user1325940 Points 21

La réponse à cette question est assez simple. EF ne pouvez pas déduire le type de la donnée à l'information que vous avez fournie.

Viens de le faire à la place:

public void RemoveEmployeeFromProject(int projectId)
{
    var project = Context.Projects.FirstOrDefault(x => x.ProjectId == projectId);
    project.EmployeeId = (int?)null;
    Context.SaveChanges();
}

et il va fonctionner.

4voto

Sprintstar Points 3665

Vous pouvez le faire de cette façon, ce qui signifie de ne pas avoir à charge de l'entité associée.

context.Entry(Project).Reference(r => r.Employee).CurrentValue = null;

0voto

David Wick Points 4997

si vous activez le chargement paresseux en faisant de l'employé de la propriété virtuelle fonctionne-t-cela?

public class Project
{
    public int ProjectId {get; set;}
    public virtual Employee Employee {get;set;}
}

je voudrais aussi suggérer l'encapsulation de la suppression de la méthode dans le cadre de votre classe poco à rendre le sens plus clair. voir cet article pour plus de détails sur ce point.

public class Project
{
    public int ProjectId {get; set;}
    public virtual Employee Employee {get;set;}
    public void RemoveEmployee()
    {
        Employee = null;
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X