2011-03-17 3 views
3

EF4 CTP5 프로젝트에서 POCO 클래스를 사용하고 있으며 하위 속성을 삭제하는 데 문제가 있습니다. 여기에 내 예가있다. (너무 길지 않기를 바란다.) 여기 투어 클래스작업 단위 패턴을 사용하여 POCO에서 하위 항목을 삭제할 수 없습니다.

public partial class Tour 
{ 
    public Guid TourId { get; private set; } 
    protected virtual List<Agent> _agents { get; set; } 

    public void AddAgent(Agent agent) 
    { 
    _agents.Add(agent); 
    } 

    public void RemoveAgent(Guid agentId) 
    { 
    var a = Agents.Single(x => x.AgentId == agentId); 
    _agents.Remove(Agents.Single(x => x.AgentId == agentId)); 
    } 
} 

명령 처리기

public class DeleteAgentCommandHandler : ICommandHandler<DeleteAgentCommand> 
{ 
    private readonly IRepository<Core.Domain.Tour> _repository; 
    private readonly IUnitOfWork _unitOfWork; 

    public DeleteAgentCommandHandler(
     IRepository<Core.Domain.Tour> repository, 
     IUnitOfWork unitOfWork 
    ) 
    { 
    _repository = repository; 
    _unitOfWork = unitOfWork; 
    } 

    public void Receive(DeleteAgentCommand command) 
    { 
    var tour = _repository.GetById(command.TourId); 
    tour.RemoveAgent(command.AgentId); 

    // The following line just ends up calling 
    // DbContext.SaveChanges(); on the current context. 

    _unitOfWork.Commit(); 
    } 
} 

관련 부분은 내 UnitOfWork에이 DbContext.SaveChanges()

를 호출 할 때 얻을 오류 발생

작업이 실패했습니다. 하나 이상의 외래 키 등록 정보가 null이 허용되지 않아 관계를 변경할 수 없습니다. 관계가 변경되면 관련 외래 키 등록 정보는 널 (NULL) 값으로 설정됩니다. 외부 키가 널값을 지원하지 않으면, 새 관계가 정의되어야하고, 외부 키 등록 정보에 널이 아닌 다른 값이 지정되어야합니다. 그렇지 않으면 관련이없는 오브젝트가 h 제되어야합니다. EF 못해 그냥 자동으로 나의 투어 클래스의 에이전트 모음에서 제거되었습니다해서 데이터베이스에서 에이전트 엔티티를 삭제하기 때문에

이 일어나고있다.

명시 적으로 dbContext.Agents.DeleteObject(a);을 호출해야하지만 내 문제는 내 POCO 내에서 dbContext에 액세스 할 수 없다는 것입니다.

이 시나리오를 처리하는 방법이 있습니까?

+0

나는 올바른 길을 가고 있다고 생각합니다. EF가 컬렉션에서 에이전트 엔티티를 제거하려고 시도하지만 TourId 외래 키 값을 null로 설정할 수 없습니다 (예 : 에이전트에 TourId 외래 키가 있음). edmx에서 둘러보기 에이전트 연결을 어떻게 선언합니까? – kdawg

+0

OnModelCreating의 Fluent API (4.1 codefirst)와 관계를 'modelBuilder.Entity () .HasRequired (p => p.Tour) .WithMany (t => t.Agents);와 같이 선언하고 있습니다. – jessegavin

답변

1

현재 아키텍처에서 DeleteAgentCommandHandler에 두 번째 저장소 (IRepository<Core.Domain.Agent>, 내가 추측)를 공급해야하고 그 다음 두 번째 저장소에서 과 같은 것을 호출해야합니다.

IUnitOfWork을 저장소 팩토리로 확장 할 수 있으므로 인터페이스에 T CreateRepository<T>()과 같은 추가 메소드가 생기므로 작업 단위에서 일반 저장소의 인스턴스를 가져올 수 있습니다. (그러면 IUnitOfWork을 더 이상 저장소가 아닌 DeleteAgentCommandHandler에 삽입하면됩니다.)

또는 비즈니스/UI 레이어의 일반 저장소에서 멀리 떨어져 있어야합니다. Agent이 완전히 Tour에 의존하는 경우 저장소가 전혀 필요하지 않습니다. 비 - 일반 ITourRepository은 데이터베이스 계층의 둘러보기에서 에이전트를 적절히 제거하는 경우를 처리 할 수있는 메소드를 가질 수 있습니다.

+0

감사합니다. 당신의 대답은 저를 슬프게하지만 도움을줍니다. – jessegavin

+0

@jessegavin : 대답의 어느 부분이 슬프게합니까? 마지막 단락이라면 나는 너와 함께 느낄 수있다. 내 자신의 앱에서 일반적인 저장소가 코드가 적지 만 불행히도 간단한 DB 작업 이외의 처리에는 충분하지 않은 좋은 패턴이라는 것을 발견했을 때 나는 슬 was다. 오늘날 나는 적어도 내부 헬퍼로서 일반적인 저장소를 사용하고 있지만 "집계 루트"를위한 비 일반 저장소로 작업하고 있습니다. 내 리포지토리에서 훨씬 많은 코드를 생성하지만 DB 계층에서 비슷한 문제를 해결하는 데 더 유연합니다. – Slauma

0

이것은 작동해야하는 것처럼 보입니다.-받는 부모 엔티티의 키를 추가 제안 (불행하게도 나는 그것을 잃어버린 곳)

http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/58a31f34-9d2c-498d-aff3-fc96988a3ddc/

나는 또 다른 게시물을 발견했습니다 :이 기능을 제안이 게시물은 향후 버전에 대한 조사되고있는 것으로 나타났습니다 이처럼 DbContext OnModelCreating 방법에서 아이 엔티티 :

modelBuilder.Entity<Agent>() 
.HasKey(AgentId) 
.HasKey(TourId); 

현재이의 상위 키를 포함하도록 XAML을 해킹하여 EDMX 파일을 사용할 때이 작업을 가지고 있지만, 코드 처음 사용하여 런타임에 예외가 발생합니다 저장소 데이터 모델 및 개념적 데이터 모델. 이 동작의 차이는 EDMX 파일의 경우 EF가 보유한 저장소 메타 데이터가 정확하다는 것을 신뢰하는 반면 코드 우선 모델은 모델 일치 여부를 확인하기 위해 코드를 먼저 확인하기 때문입니다.

아직 시도하지는 않았지만 다른 방법은 자식 테이블에 부모 키를 복합 키로 포함하여 코드 우선이 행복하도록하는 것입니다. 분명히 데이터베이스를 변경하거나 XAML을 해킹하는 것이 가장 이상적이고 해결 방법이 적습니다.

관련 문제