Я довольно новичок в платформе Entity Framework, и это также моя первая публикация на Stack Overflow, так голая со мной, пожалуйста.Entity Framework сохраняет слишком много дочерних объектов
Я работаю над проектом, который состоит из нескольких объектов, которые я хочу сохранить в моей базе данных. Я использую один контекст и ряд классов репозитория для доступа к ним.
Когда я пытаюсь сохранить объект, он сохраняет все связанные с ним виртуальные объекты, даже если этот объект уже существует в базе данных.
Это мои классы:
public class Requirement
{
public int ID { get; set; }
public DateTime DateDue { get; set; }
public DateTime DateCompleted { get; set; }
public virtual Standard Standard { get; set; }
public virtual Project Project { get; set; }
}
public class Standard
{
public int ID { get; set; }
public int AgencyID { get; set; }
public string Name { get; set; }
public virtual Agency Agency { get; set; }
}
public class Project
{
public int ID { get; set; }
public bool Active { get; set; }
public virtual Agency Agency { get; set; }
public virtual Department Department { get; set; }
}
И это метод я для создания некоторых данных:
public class RequirementRepository
{
public static string CreateMockData()
{
StandardRepository stdRep = new StandardRepository();
ProjectRepository projRep = new ProjectRepository();
RequirementRepository reqRep = new RequirementRepository();
Project project = projRep.Find(1);
StringBuilder sb = new StringBuilder()
foreach (Standard s in stdRep.FindByAgencyID(project.Agency.ID))
{
Requirement r = new Requirement();
r.Project = project;
r.Standard = s;
r.DateCompleted = (DateTime)SqlDateTime.MaxValue;
r.DateDue = DateTime.Now.AddDays(90);
r = reqRep.Save(r);
sb.AppendLine(String.Format("Saved Requirement ID {0} with Project ID {1}<br>", r.ID, r.Project.ID));
}
return sb.ToString();
}
}
И здесь связан код хранилища:
public class ProjectRepository
{
public Project Find(int id)
{
using (var db = new MyContext())
{
return db.Projects
.Include(p => p.Agency)
.Include(p => p.Department)
.First(p => p.ID.Equals(id));
}
}
}
public class StandardRepository
{
public List<Standard> FindByAgencyID(int agencyID)
{
using (var db = new MyContext())
{
return db.Standards.Where(r => r.AgencyID == agencyID).ToList();
}
}
}
public class RequirementRepository
{
public Requirement Save(Requirement requirement)
{
using (var db = new MyContext())
{
Requirement retVal = requirement;
if (requirement.ID.Equals(0))
{
retVal = db.Requirements.Add(requirement);
}
else
{
db.Entry(requirement).State = EntityState.Modified;
}
db.SaveChanges();
return retVal;
}
}
}
Когда Я запускаю этот метод, я ожидаю, что он добавит несколько новых требований в базу данных с идентификатором проекта 1 и стандартный идентификатор любого стандарта, в котором он включен. Вместо этого он создает совершенно новый проект и совершенно новый стандарт для каждого добавляемого требования, а затем присваивает эти идентификаторы этому требованию.
Как я, так и мой наставник (который также является новичком в Entity Framework) очень смущены, и я не могу найти ничего об этом в другом месте. Я надеялся, что кто-то здесь сможет помочь.
Заранее благодарен!
Возможно, ваша проблема сохраняется в другом контексте, чем тот, который использовался для извлечения вашего проекта и стандартных экземпляров. – B2K
@ B2K вы говорите, что он должен удалить операторы 'using' и сделать' db' переменной класса? – Jonesopolis
@ Jonesy не совсем. Проблема сложнее, просто переместив контекст в переменную класса. Он извлекает объекты из разных контекстов, а затем пытается сохранить их в новый контекст. Все они должны быть восстановлены и сохранены с использованием одного и того же. См. Принятый ответ ниже. – B2K