연결이 끊긴 dbcontext는 탐색 속성을 업데이트하지 않습니다.
문제
먼저 코드를 사용하여 WebAPI 2.0 및 EF6.0을 사용하여 API를 작성하고 있습니다.따라서 반드시 연결이 끊긴 dbcontext 시나리오입니다.
내 도메인은 아래와 같습니다
public class Patient
{
public int Id { get; set; }
public string Name { get; set; }
public string Email ( get; set; }
public virtual Nutritionist Nutritionist { get; set; }
}
public class Nutritionist
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<Patient> Patients { get; set; }
}
UI를 통해 환자는 현재 영양사가 만족스럽지 않은 경우 다른 영양사를 선택할 수 있습니다.따라서 내 API가 이를 지원해야 합니다.나는 이것이 환자에 대한 간단한 업데이트일 것이라고 생각했습니다.그러나 다음 단위 테스트는 실패합니다.
[TestMethod]
public void Changing_Nutritionist_In_Disconnected_Context_Works()
{
Patient p;
Nutritionist n;
using (var c = new Context())
{
// Get a patient where I know p.Nutritionist.Id == 1 in database.
p = c.Patients.Find(1);
// Get some other nutritionist
n = c.Nutritionists.Find(3);
}
using (var c = new Context())
{
//change patient's email and nutritionist
p.Email = "patient@domain.com";
p.Nutritionist = n;
c.Patients.Attach(p);
c.Entry(p).State = EntityState.Modified;
c.SaveChanges();
}
using (var c = new Context())
{
Assert.AreEqual(3,c.Patients.Find(1).Nutritionist.Id);
}
}
나는 그것을 예상했다 SaveChanges()
환자의 두 속성에 대한 변경 사항을 저장합니다. p.Email
그리고 p.Nutritionist
.하지만 데이터베이스에서는 이메일만 변경되고 Nutritionist_Id
필드에 계속 이전 값이 표시됩니다.따라서 어떤 이유로 dbContext는 탐색 속성의 변경 사항을 무시합니다. p.Nutritionist
SQL 프로파일러는 EF에서 실행된 다음 UPDATE 쿼리를 보여줍니다.
exec sp_executesql N'UPDATE [dbo].[Patients]
SET [Name] = @0, [Email] = @1
WHERE ([Id] = @2)
',N'@0 nvarchar(max) ,@1 nvarchar(max) ,@2 int',@0=N'some name',@1=N'patient@domain.com',@2=1
go
내가 무엇을 놓칠 수 있는지 궁금합니다.
해결책
예, 명시적인 속성을 사용할 수 있습니다 p.NutritionistId
하지만 저는 단지 순수주의자가 되려고 노력했을 뿐입니다 :)
다음 코드가 작동한다는 것을 알았습니다 ...
cn.Patients.Attach(p);
cn.Nutritionists.Attach(n);
cn.Entry(p).Reference(x => x.Nutritionist).Load();
p.Nutritionist = n;
cn.Entry(p).State = EntityState.Modified;
cn.SaveChanges();
EF는 자동으로하지 않는 것 같습니다 붙이다 관련 항목... p.Nutritionist
이 경우.
또한 거트 아놀드 위의 주석에서 언급한 내용도 로드되지 않습니다.
따라서 명시적으로 로드 p.Nutritionist
그런 다음 연결된 엔터티로 값을 변경하면 EF가 행복해집니다.
새 엔터티를 연결하고 EntityState.Modified
, 스칼라 속성만 저장하는 것이 아니라 전체를 저장하고 싶습니다.