문제

나는 물체 사이에 다중 관계가 있습니다 Product 그리고 Supplier. 삭제할 수 있어야합니다 Supplier 삭제하지 않고 Product그것에 속한 s.

다음은 단순화 된 클래스 버전입니다.

public class Supplier {
    public virtual IList<Product> Products { get; protected set; }
}

public class Product {
    // Product belongs to a Category but Supplier is optional
    public virtual Supplier Supplier { get; set; }
    public virtual Category Category { get; set; }
}

나는 fluentnhibernate를 사용하고 있지만 여기에 생성 된 매핑이 있습니다.

<bag name="Products" cascade="save-update" inverse="true">
      <key column="SupplierID" />
      <one-to-many class="Me.Product, Me, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>

<many-to-one name="Supplier" column="SupplierID" />

이것은 제품 테이블에 외국 키를 생성하므로 공급 업체에서 직선 삭제를 시도 할 때 외국 키 제약 조건 오류가 발생합니다. 나는 Cascade를 'All'으로 바꾸려고 시도했지만 관계는 삭제 될 수 있기를 희망했지만 모든 제품과 다른 관련 객체를 삭제했습니다.

지금이 문제를 해결할 수있는 유일한 방법은 공급 업체의 제품 수집을 반복하고 공급 업체 자산을 NULL로 설정하는 것입니다. 매핑을 통해이 동작을 달성 할 수있는 방법이 있습니까?

도움이 되었습니까?

해결책

매핑 속성은 엔티티가 실제로로드 된 경우에만 적용되며 HQL을 통해 쿼리하지 않을 때만 적용됩니다. 예를 들어, 지정하는 경우 Cascade=ALL, 쿼리와 함께 공급 업체를 삭제하는 경우 "delete from Supplier where id=:id", HQL이 (프로그래밍 방식) 캐스케이드를 트리거하지 않기 때문에 동일한 FK 제약 조건 고장이 발생할 수 있습니다.

제품은 관계의 소유 측면 인 것 같습니다. 두 가지 선택이 있다고 생각합니다.

  • 공급 업체의 일부 방법을 코딩하여 모든 제품을 반복하고 제품 공급 업체를 NULL로 설정하고 공급 업체를 삭제하기 전에이 방법을 사용하십시오.
  • 공급 업체 삭제를 발행하기 전에 DAO가 제품 공급 업체를 NULL로 설정했는지 확인하십시오.

예시:

public int Delete(Supplier s) {
    return Session.CreateQuery("udpate Product set Supplier = null where Supplier = :supplier")
        .SetParameter("supplier", s)
        .ExecuteUpdate();
}

다른 팁

이것을하지 마십시오.

귀하의 모델에는 모든 제품에 공급 업체가 있다는 암시 적 또는 명시 적 주장이 있습니다. 이 조건을 시행하기 위해 외국 키가 있습니다. 제품을 유지하면서 공급 업체를 제거하면 모델을 위반하면 코드의 많은 부분이 생길 수 있습니다.

당신이 할 수있는 한 가지는 이미 발견했습니다.이 공급 업체가있는 모든 제품에 대해 제품 공급 업체를 NULL을 설정할 수 있습니다. 이것은 귀하의 상태를 위반하지는 않지만 "이 제품의 공급 업체가 누구인지 모릅니다"라고 말하는 것과 동일하며 코드 실패를 유발할 수 있습니다.

왜 이것을하고 싶습니까?

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