Q & A

시삽: 레드플러스 님 
게시판 이동:
 제목 : Re : Re : ef core 캐시 비활성화시 업데이트 방법 문의
글번호: 895
작성자: 안정준
작성일: 2020/10/26 오후 3:38:00
조회수: 2370

 

답변해 주셔서 감사합니다.

제가 좀더 살펴보니 ServiceLifetime.Transient 는 페이지가 이동되지 않는한 새로운 인스턴스를 만들지 않는 것 같습니다. 그래서 EF Core에서 한번 읽어온 데이터를 캐쉬하고 있어 읽어온 데이터를 다른 사람이 수정해도(동시에 같은 자료 편집시) 다시 쿼리를 수행해도 읽어온 데이터를 업데이트하지 않고 있습니다. 다른 페이지로 이동후 다시 해당 페이지로 이동하면 예상한대로 새로운 인스턴스를 생성하고 변경된 데이터를 가져옵니다. 그래서 캐시를 무시하게 위하여 NoTracking 옵션을 주어 같은 인스턴스 같은 데이터를 쿼리시 수정된 데이터를 가져오도록 했습니다. 그런데 특정 row 업데이트시 한번은 업데이트가 되는데 두번째 업데이트시 말씀드린 에러가 발생했습니다.

 우연챃게 구글에서 찾은 자료에는(Entry대신 Attacha로)  _context.Attach(model).State = EntityState.Modified; 이문장만 적용하면 된다고 했는데 저는 안되더라구요. 역시 동일한 에러메세지가 나고요 ㅠㅠ 결국 navigationManager.NavigateTo("/...",forceLoad:true);로 강제로 페이지를 로드하여 수정된 자료를 가져오도록 했습니다.


On 2020-10-26 오전 11:52:00, '레드플러스' wrote:

 

 


 

안녕하세요.

Blazor 강좌는 Part 3-1로 우선 공개했습니다.

너무 시간이 오래걸릴 것 같아서, Part 3-1, 3-2 형태로 제공될 예정입니다.

 

말씀주신 부분은 저도 처음에 경험을 했던 에러메시지인데요.

지금은 따로 이것을 만나지 않고 있어서,

제 소스를 찾아보니,

제 경우에는

(1)

DbContext 클래스의 생성자에서 아래 코드는 오히려 주석을 처리해두었고,

// ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

(2)

DI 컨테이너에 등록하는 Startup.cs 파일의 코드는 다음처럼 모든 코드 뒤에 ServiceLifetime.Transient 옵션을 두었습니다.

services.AddEntityFrameworkSqlServer().AddDbContext<NoticeAppDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient);
 

이 외에는 따로 처리한 사항은 없구요.

평상시 개발하는 형태로 CRUD를 진행하고 있습니다.

이 부분의 기능을 한번 검토해보세요.

다음 경로처럼,

2군데 소스를 테스트로 적용해보시는 것도 좋을 것 같습니다.

https://github.com/VisualAcademy/Hawaso/commit/955b3059d7f84e0302165269d31da4b0cdd70bf0#diff-f1c1e2218ffc7fe8070a8862b74b227392ee766bc50235103bda6e113df28358

 

이상입니다.

 

 


On 2020-10-26 오전 10:22:00, '안정준' wrote:

 

 


안녕하세요 블레이저강의 3번째 편이 올라와서 반가웠습니다.

 

블레이저로 개발을 하고 있는데 한가지 문제가 부닥쳤습니다.

 

ef core 로 repository를 만들어 블레이저 페이지내에서  DI를 사용했는데

리스트를 GetAllAsync후 DB에서 자료를 수정했을때 다시 GetAllAsync하면 수정된 자료가 반영이 되지 않습니다. 그래서 구글링해서

 

_context.ChangeTracker.QueryTrackingBehavior = Microsoft.EntityFrameworkCore.QueryTrackingBehavior.NoTracking; 트랙킹을 비활성화 해서

수정된 자료로 검색하는데는 성공했습니다.

그런데 문제가 수정에서 또 발생했습니다.

public async Task<bool> EditAsync(EX_EVENT model)
{

        _context.tbl_EX_EVENTS.Attach(model);;
         _context.Entry(model).State = EntityState.Modified;
         return (await _context.SaveChangesAsync() > 0 ? true : false);

}

EditAsync로 수정시 한번은 수정이 되나 두번째 같은 자료를 EditAsync 하면

Message = "The instance of entity type 'EX_EVENT' cannot be tracked because another instance with the same key value for {'EX_EVENT_NUM'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attach...

이런 에러가 뜹니다.

트랙킹을 활성화하고 아예 페이지를 강제로 리로드하면 DI가 다시 생성이 되어 최근 데이터로 검색도 되고 문제는 안생기는 추후 scope를 사용하면 다 날라가게되어 좋은 방법이 아닌것 같아 방법을 찾고 있습니다.

그리고 혹시 페이지를 리로드 하지 않고도 DI를 재 생성할 수 있는 방법이 있을까요?

 

결국 이러다 ef core 포기하고 dapper로 가야하나 고민중입니다.

 
이전 글   다음 글 삭제 수정 답변 글쓰기 리스트
  Administrator
  2020-10-26 오후 7:21:14
어떻게보면, 지금 해결하신 방법이 가장 최선이 아닐까합니다^^
저도 생각해보니, 몇몇 페이지에는 강제 리로드를 사용한 기억이 나네요...

(댓글을 남기려면 로그인이 필요합니다.)

관련 아티클 리스트
  제       목 파일 작성자 작성일 조회
이전글 asp.net &amp; core 를 다루는 기술 게시판 코드boardeditorFo... - 강현우 2020-11-11 2131
  ef core 캐시 비활성화시 업데이트 방법 문의 - 안정준 2020-10-26 2247
  Re : ef core 캐시 비활성화시 업데이트 방법 문의 - 레드플러스 2020-10-26 2095
현재글 Re : Re : ef core 캐시 비활성화시 업데이트 방법 문의(1) - 안정준 2020-10-26 2370
다음글 blazor server-side에서 cmd 창 띄우기 - 김동환 2020-10-24 2281
 
손님 사용자 Anonymous (손님)
로그인 Home