EF4를 사용하고 있으며 처음 사용하고 있습니다. 내 프로젝트에 다대 다가 있고 삽입 또는 업데이트 방법을 해결할 수없는 것 같습니다. 코딩 방법을보기 위해 작은 프로젝트를 빌드했습니다.
테이블이 3 개 있다고 가정 해 보겠습니다.
- 클래스 : ClassID-ClassName
- 학생 : StudentID-FirstName-Surname
- StudentClass : StudentID-ClassID
모든 관계를 추가하고 모델 브라우저를 통해 모델을 업데이트 한 후 StudentClass가 나타나지 않는 것으로 나타났습니다. 이것이 기본 동작 인 것 같습니다.
이제 삽입과 업데이트를 모두 수행해야합니다. 어떻게하나요? 예제를 다운로드 할 수있는 코드 샘플이나 링크가 있습니까? 아니면 5 분 정도 여유가 있습니까?
답변
엔터티 (또는 개체)의 관점 Class
에서 컬렉션이 Students
있는 Student
개체 와 컬렉션이 있는 개체가 있습니다 Classes
. 당신 때문에 StudentClass
테이블에만 ID와 별도의 정보를 포함, EF는 가입 테이블에 대한 엔티티를 생성하지 않습니다. 그것은 올바른 행동이며 당신이 기대하는 것입니다.
이제 삽입이나 업데이트를 할 때 객체의 관점에서 생각하십시오. 예를 들어 두 명의 학생이있는 클래스를 삽입하려면 Class
객체, Student
객체를 만들고 학생을 클래스 Students
컬렉션에 추가 Class
하고 컨텍스트에 객체를 추가 하고 다음을 호출합니다 SaveChanges
.
using (var context = new YourContext())
{
var mathClass = new Class { Name = "Math" };
mathClass.Students.Add(new Student { Name = "Alice" });
mathClass.Students.Add(new Student { Name = "Bob" });
context.AddToClasses(mathClass);
context.SaveChanges();
}
이것은에 항목이 만들어집니다 Class
테이블의 두 엔트리 Student
테이블과 두 개의 항목 StudentClass
들을 함께 연결 테이블을.
기본적으로 업데이트에 대해 동일하게 수행합니다. 데이터를 가져오고 컬렉션에서 개체를 추가 및 제거하여 그래프를 수정하고 SaveChanges
. 자세한 내용은 이 유사한 질문 을 확인 하십시오.
편집 :
귀하의 의견에 따라 새 항목을 삽입하고 Class
두 개의 기존 항목 Students
을 추가 해야합니다.
using (var context = new YourContext())
{
var mathClass= new Class { Name = "Math" };
Student student1 = context.Students.FirstOrDefault(s => s.Name == "Alice");
Student student2 = context.Students.FirstOrDefault(s => s.Name == "Bob");
mathClass.Students.Add(student1);
mathClass.Students.Add(student2);
context.AddToClasses(mathClass);
context.SaveChanges();
}
두 학생이 이미 데이터베이스에 있으므로 삽입되지 않지만 이제 Students
.NET 컬렉션에 있으므로 Class
두 항목이 StudentClass
테이블에 삽입됩니다 .
답변
업데이트를 위해 이것을 시도하십시오.
[HttpPost]
public ActionResult Edit(Models.MathClass mathClassModel)
{
//get current entry from db (db is context)
var item = db.Entry<Models.MathClass>(mathClassModel);
//change item state to modified
item.State = System.Data.Entity.EntityState.Modified;
//load existing items for ManyToMany collection
item.Collection(i => i.Students).Load();
//clear Student items
mathClassModel.Students.Clear();
//add Toner items
foreach (var studentId in mathClassModel.SelectedStudents)
{
var student = db.Student.Find(int.Parse(studentId));
mathClassModel.Students.Add(student);
}
if (ModelState.IsValid)
{
db.SaveChanges();
return RedirectToAction("Index");
}
return View(mathClassModel);
}
답변
나는 그것에 내 경험을 추가하고 싶었습니다. 실제로 EF는 컨텍스트에 개체를 추가하면 모든 자식 및 관련 엔터티의 상태가 추가됨으로 변경됩니다. 여기 규칙에는 작은 예외가 있지만 자식 / 관련 엔터티가 동일한 컨텍스트에서 추적되는 경우 EF는 이러한 엔터티가 존재한다는 것을 이해하고 추가하지 않습니다. 예를 들어 다른 컨텍스트 또는 웹 UI 등에서 자식 / 관련 엔터티를로드 한 다음 예, EF는 이러한 엔터티에 대해 아무것도 모르고 모두 추가 할 때 문제가 발생합니다. 이를 방지하려면 엔티티의 키를 가져 와서 찾으십시오 (예 : context.Students.FirstOrDefault(s => s.Name == "Alice"))
추가를 수행하려는 동일한 컨텍스트에서).
답변
외래 키만 관련된 다 대다 관계를 처리하기 위해 다음 방법을 사용합니다.
따라서 삽입 :
public void InsertStudentClass (long studentId, long classId)
{
using (var context = new DatabaseContext())
{
Student student = new Student { StudentID = studentId };
context.Students.Add(student);
context.Students.Attach(student);
Class class = new Class { ClassID = classId };
context.Classes.Add(class);
context.Classes.Attach(class);
student.Classes = new List<Class>();
student.Classes.Add(class);
context.SaveChanges();
}
}
대한 삭제 ,
public void DeleteStudentClass(long studentId, long classId)
{
Student student = context.Students.Include(x => x.Classes).Single(x => x.StudentID == studentId);
using (var context = new DatabaseContext())
{
context.Students.Attach(student);
Class classToDelete = student.Classes.Find(x => x.ClassID == classId);
if (classToDelete != null)
{
student.Classes.Remove(classToDelete);
context.SaveChanges();
}
}
}
답변
개체 프레임 워크에서 개체가 컨텍스트에 추가되면 해당 상태가 추가됨으로 변경됩니다. EF는 또한 개체 트리에 추가 할 각 개체의 상태를 변경하므로 기본 키 위반 오류가 발생하거나 테이블에 중복 레코드가 추가됩니다.