2009-10-31 6 views
1

Order 엔티티가 OrderDetails리스트를 가지고 있다면, NHibernateUtil.Initialize (Order.Details)를 사용하여 그 순서와 함께 세부 정보를 쉽게 열망 할 수있다. 그래서 분명히 NHibernate는 SQL 문을 생성하기위한 모든 정보를 가지고 있습니다. 그러나 수동으로 조건을 만들지 않고 세부 정보 (Entity Framework의 CreateSourceQuery와 유사) 만 데이터베이스에 쿼리하려면 어떻게해야합니까? NHibernateUtil.GetList (Order.Details)와 같은 것이 있습니까?NHibernate의 Reload association/related collection

업데이트 : 대린의 대답을 사용하여 결국 나는 결국 끝이났습니다. 이것은 내가 중 하나 Criteria API 또는 HQL을 사용하고 개체의 기본 클래스

Dim entity as EntityBase 
Dim queryString = String.Format("select entityAlias.{1} from {0} entityAlias where entityAlias.id = :ID", entity.GetType.Name, collectionPropertyName) 
Dim query = Session.CreateQuery(queryString).SetParameter("ID", entity.ID) 
Return query.List 

답변

1

NHibernate에는 사용자가 묻고있는 것처럼 정확하게 수행 할 수있는 메서드가 내장되어 있습니다. (ISession.CreateFilter)

예를 들어 Orders라는 Orders 컬렉션이있는 Customer라는 고객이로드 된 경우이 작업을 수행하여 주문을로드 할 수 있습니다.

var orderQuery = session.CreateFilter(customer.Orders, string.Empty); 
var orders = orderQuery.List<Order>(); 

이것은 약간의 청소기로 다음과 동일합니다.

var orderQuery = session.CreateQuery("from orders o where o.Customer.id = :customerId") 
         .SetParameter("customerId", customer.Id); 
var orders = orderQuery.List<Order>(); 

당신은 수집, 절은 내가 엔티티을하는 일반적인 방법을 만들 수 있도록하려면 ISession.CreateFilter(object, string)

+0

감사합니다. 이것은 내가 찾고 있었던 바로 그 것이다. 나는 필터를 사용하는 것을 결코 생각하지 못했다. 실제로 쿼리를 수행했습니다 (두 번째 예제). –

1

에 NHibernate에있는 개체를 쿼리의 권장 방법을 구현할 수있는 정도로 일반적인 것입니다. 이 두 가지 접근법에 대해 어떤 이유가 있습니까?

var details = session.CreateCriteria<OrderDetails>().List<OrderDetails>(); 
var details = session.CreateQuery("from OrderDetails").List<OrderDetails>(); 

UPDATE :

당신은 다음과 같은 쿼리를 사용할 수있는 부모 개체를로드하지 않고 단지 연결을로드하려면 :

var details = session.CreateQuery(
     "select " + 
     " orderDetail" + 
     "from " + 
     " Order order," + 
     " OrderDetail orderDetail " + 
     "where " + 
     " orderDetail in elements(order.Details)" 
    ) 
    .List<OrderDetail>(); 
+0

에 두 번째 인수로 전달 될 수있는 HQL을 필터링 할, 그리고 협회의 경우 경로를 찾고 관련 목록 (이 경우 OrderDetails)을 리턴하십시오. createCriteria를 사용하여 제한 Order.ID = xx를 지정해야합니다. NHibernate는 이미이 정보를 가지고 있고 엔티티 프레임 워크의 CreateSourceQuery 메소드와 동일한 것이 있는지 궁금합니다. –

+0

'Order' 인스턴스를 얻으면'order.OrderDetails' 연관을 사용하여 세부 정보를 가져옵니다. –

+0

대린 감사합니다. 나는 이것을 사용할 수 있다고 생각한다. –

1

이유는 바로로드하지 주문을하고 세부 컬렉션에 액세스 하시겠습니까? 컬렉션을로드 할 수만 있다면 관계에 Order가 필요하기 때문에 컬렉션에 추가 할 수 없습니다.

나는 당신이 NHibernateUtil.Initialize를 오용하고 있다고 생각한다. 그 목적은 특별한 경우에 프록시 콜렉션 (lazy loaded)의 초기화를 강제하는 것이다. 열정적 인로드는 느린로드와 반대입니다. 그 시나리오에서 컬렉션은 항상 부모 객체와 함께로드되고 프록시는 필요하지 않습니다. Order 객체가 이미있는 경우 Details 컬렉션에 액세스하면 해당 객체가로드됩니다. 열망하는 가져 오기를 원하면 매핑 옵션에서 설정할 수 있습니다.

+0

나는 NHibernateUtil.Initialize를 사용하여 필요한 쿼리를 설명했다. 내 경우에 이미 Order와 관련 세부 정보를로드했지만 세부 정보를 다시로드해야하는 변경 사항이있을 것입니다.Order 및 Details (SetFetchMode 사용)를 새로 고치는 기준을 쉽게 만들 수 있지만 세부 정보 만 얻는 방법이 필요합니다. NHibernate가 이미 내부적으로 가지고있는 정보를 재생성하지 않고서도 이것을 얻는 함수 나 사소한 방법이 이미 있기를 바랬다. –

+0

세부 정보를 다시로드해야하는 이유를 확장 할 수 있습니까? 트리거 동작과 같은 데이터베이스 변경 사항을 가져와야하는 경우 ISession.Refresh()를 호출하거나 새 ISession에서 Order를 다시로드 할 수 있습니다. –

+0

예 트리거에 의해 변경된 사항이 있습니다. 내가 뭘 하려는지 세부 사항을 얻을 경우에만이 경우에는 그 유일한 변경 사항을 알고 이후 Order.Details 수동으로 다시 병합합니다. 이 특별한 경우에만 세부 사항 만 변경되기 때문에 다른 세션에서 새로 고침 또는 다시로드하는 순서는 불필요한 데이터 페치 (주문 및 기타 변경되지 않은 연결로드)를 수행합니다. –