문제

먼저 코드를 사용하여 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, 스칼라 속성만 저장하는 것이 아니라 전체를 저장하고 싶습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top