Entity Framework 데이터베이스 컨텍스트 (모델)를 MVVM WPF의 ViewModel에 연결하는 가장 좋은 방법은 무엇입니까?


9

위의 질문에서와 같이 : Entity Framework 데이터베이스 모델 (컨텍스트)을 MVVM (WPF)의 viewModel에 연결하는 가장 좋은 방법은 무엇입니까?

WPF에서 MVVM 패턴을 배우고 있습니다. 많은 예제는 모델을 viewModel에 구현하는 방법을 보여 주지만 해당 예제의 모델은 단순한 클래스이므로 엔터티 프레임 워크 모델과 함께 MVVM을 사용하고 싶습니다 (기본 우선 접근법). 모델을 viewModel에 연결하는 가장 좋은 방법은 무엇입니까?

답변 주셔서 감사합니다.

//ctor of ViewModel 
public ViewModel()
{ 
db = new PackageShipmentDBEntities(); // Entity Framework generated class

ListaZBazy = new ObservableCollection<Pack>(db.Packs.Where(w => w.IsSent == false)); 
}

이것은 ViewModel의 일반적인 ctor입니다. 더 나은 방법이 있다고 생각합니다. 리포지토리 패턴에 대해 읽었습니다 .WPF MVVM에 맞게 조정할 수 있는지 확실하지 않습니다.

답변:


4

나는 이것에 대해 조금 살펴 보았고 "완벽한"해결책을 찾지 못했다. 리포지토리 패턴은 컨텍스트가 짧은 라이브 컨트롤러에 있기 때문에 컨텍스트가 짧은 라이브 인 MVC 응용 프로그램에서 훌륭하게 작동하지만 VM이 오랫동안 지속될 수있는 wpf 앱에 동일한 구조를 적용하려고하면 문제가 발생합니다.

나는 과거 에이 솔루션을 사용하여 많은 레포 패턴보다 훨씬 간단합니다. 여러분을 극단으로 추상화하려고 시도하여 읽을 수없는 양의 코드를 디버깅하기가 어렵습니다. 단계는 다음과 같습니다.

  1. EDMX가 데이터 액세스 계층으로 작동 할 별도의 프로젝트를 만듭니다.
  2. 동일한 프로젝트에서 "리포지토리"폴더 생성
  3. "작업 단위"로 작동 할 기본 클래스 "BaseRepository"를 작성하십시오. IDisposable에서 이것을 사용할 수 using(){}있고 partial다른 저장소를 구현할 수 있습니다.

    public partial class MyEntityRepository : IDisposable
    {
        MyEntities context = new MyEntities();
    
        public void Dispose()
        {
            context.Dispose();
        }
    }
  4. "MyOtherRepository"라는 다른 파일을 작성하십시오. 동일한 부분 클래스를 작성하지만 파일에 포함하려는 내용을 기반으로 메소드를 구현하십시오.

    public partial class MyEntityRepository
    {
        public void MyOtherMethodSave(EntityObject obj)
        {
            //work with context
            ...
    
            context.SaveChanges();
        }
    }

이제 VM 에서이 작업을 수행 할 수 있습니다 ...

using(MyEntityRepository repo = new MyEntityRepository())
{
     repo.MyOtherMethodSave(objectToSave);
}

모든 리포지토리를 하나의 클래스로 그룹화하므로 별도의 컨텍스트를 처리 할 필요가 없습니다. 메소드를 다른 파일로 그룹화하여 다른 리포지토리를보다 잘 관리하고 코드 중복을 방지 할 수 있습니다. 또한,이 패턴을 사용하지 않는 것처럼 컨텍스트의 수명이 짧습니다.

단점은 더 큰 시스템에서는 리포지토리에 번들로 제공되는 많은 방법이있을 수 있다는 것입니다. 이 경우 하나의 솔루션은 "찾기"또는 "추가"와 같은 몇 가지 기본 공통 명령을 구현하고 해당 저장소에서 특수 명령을 구현하는 것입니다.


2
'MyEntityRepository'EF 자체 컨텍스트를 대체 할 수 있으며 동일한 결과를 얻습니다. EF의 컨텍스트를 자신의 "저장소"로 감싸고 싶지 않다면 중복이 증가합니다.
Euphoric

@Euphoric 예, 가능하지만 리포지토리가 컨텍스트에서 사용된다는 보장은 없습니다. 요점은 EF가 간단한 비즈니스 요구 사항으로 작동하는 방식을 추상화하는 것입니다.
Shoe

4

내가 좋아하지 않는 저장소와 반대. Ayende 가 권장하는 명령 패턴을 사용하는 것이 좋습니다 .

간단히 말해서 각 작업마다 별도의 ThisOperationCommand클래스 를 만듭니다 . 이 수업에서는 일반적인 EF 컨텍스트로 작업합니다. EFCommand배관 작업을 수행하는 기본 클래스 를 사용할 수도 있습니다.

ViewModel 측 에서이 명령의 인스턴스를 만들고 매개 변수로 채 웁니다 (명령과 ViewModel 사이의 긴밀한 연결을 신경 쓰지 않으면 전체 ViewModel 인스턴스를 전달할 수도 Execute있음). 명령을 실행하고 실행 한 다음 해제 한 다음 명령이있는 것을 반환하십시오. 실행 후 명령 인스턴스에서 가져 오면 여러 값을 반환하도록 할 수도 있습니다.

장점은 전체 데이터 액세스 계층을 리포지토리로 복제 할 필요가 없으며이를 지원하기 위해 간단한 인프라를 생성하는 한 명령을 재사용하고 구성 할 수 있다는 것입니다. 예를 들어 다른 명령에서 명령을 실행합니다.


0

간단한 시나리오를 위해 다음을 사용했습니다.

public class ViewModel : IDisposable {

    private EntitiesContext _context = new EntitiesContext();

    private SomeEntity _model;
    public SomeEntity Model {
       get { return _model; }
    }

    public View(int id) {
        _model = _context.SomeEntity.Find(id);
    }

    private ICommand _saveCommand = new RelayCommand(() => _context.SaveChanges());
    public ICommand SaveCommand {
        get { return _saveCommand; }
    }        

    public void Dispose() {
         _context.Dispose();
    }

}

1
이것의 문제점은 당신의 상황이 이제 잠재적으로 "장수"라는 것입니다.
구두

1
클래스 내에서 컨텍스트 인스턴스를 작성하지 말고 대신 생성자에 삽입하십시오.
Oscar Mederos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.