2009-05-04 4 views
0

메시지 테이블에 기본 키 (Id)와 외래 키 (Site)가있는 상황이 있습니다. 모든 사이트는 메시지 레코드를 만들 수 있지만 레코드를 만든 사이트 만 업데이트 할 수 있습니다. 문제는 기본적으로 Id 및 Site가 아니라 Id를 기준으로 업데이트된다는 것입니다. 기본 키를 ID와 사이트로 구성된 복합/복합 ID로 변경하거나 원시 SQL로 변경할 수 있습니다. 그러나 추가 업데이트 기준을 추가하는 방법이 있는지 궁금합니다.NHibernate를 사용하여 업데이트 명령에 추가 기준을 어떻게 추가합니까?

예를 들어

, 이것은 기본적으로 무엇을 얻을 수 있습니다 :

 
public void MessageUpdate(Message oneMessage) 
{ 
    using(ISession session = SessionFactory.OpenSession()) 
    using(ITransaction trans = session.BeginTransaction()) 
    { 
     session.Update(oneMessage); 
     trans.Commit(); 
    } 
} 

그래서 어떻게 네이티브 SQL을 복합 ID를 만들거나 사용하지 않고 자 NHibernate에서이 작업을 수행 할 : 내가 이해

 
Update MessageTable set MessageStatus = 2 where Id = ? and Site = ?; 
+0

부수적으로, session.Update는 코드에서 필요하지 않습니다. 이것에 대한 자세한 내용은 http://www.tobinharris.com/past/2009/6/11/nhibernate-calling-update-unnecessarily/ – autonomatt

답변

0

내 원래 질문에 대한 간단한 대답은 업데이트에 조건을 추가 할 수 없다는 것입니다. 원래 제안한대로 원시 SQL을 사용하여이 상황을 처리 할 수 ​​있습니다.

업데이트 MessageTable set MessageStatus = 2 여기서 Id =? 및 사이트 =?;

또는 Jamie Ide가 제안한대로 문제에 접근 할 수 있지만 원본 메시지를 가져 오기 위해 데이터베이스에 대해 추가 쿼리가 필요합니다.

0

귀하의 질문에 규칙은 비즈니스 요구 사항, 그래서 아마 NHibernate이 규칙에 장소가 아닙니다. 업데이트 이벤트에 리스너를 구현할 수 있습니다. http://nhibernate.info/blog/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.html

다른 해결책은 false로 업데이트 속성을 표시하여 레코드 사이트가 변경되지 않도록 하시겠습니까? http://nhibernate.info/doc/nh/en/index.html#mapping-generated는 (생성 된 속성을 참조하십시오)

+0

보안 규칙은 "사용자가 가지고 있지 않은 사이트의 메시지 레코드를 업데이트 할 수 없습니다 액세스". 사용자 로그온이 손상되면 공격자는 주어진 사이트와 관련된 메시지를 엉망으로 만들 수 있습니다. 추가 업데이트 조건을 추가 할 수 있다면 사용자로부터 들어오는 ID와 상태를 가져 와서 데이터베이스에서 사이트 ID를 가져올 수 있습니다. 그런 다음 id, siteid 및 status를 사용하여 업데이트 문을 작성할 수 있습니다. 따라서 사이트에 액세스 할 수없는 사용자가 다른 사이트의 레코드를 엉망으로 만들 수는 없습니다. –

0

당신은 NHibernate에 직접 그것을 할 수 있지만 당신이 당신의 업데이트 방법을 변경할 수 : 사이트를 가정

public void MessageUpdate(Message oneMessage, string currentSite) 
{ 
    if (oneMessage.Site != currentSite) 
    { 
     throw new Exception("meaningful error message"); 
    } 
    using(ISession session = SessionFactory.OpenSession()) 
    using(ITransaction trans = session.BeginTransaction()) 
    { 
     session.Update(oneMessage); 
     trans.Commit(); 
    } 
} 

문자열 및 메시지의 속성입니다. 또한 예외가 발생하면 try..catch에서 트랜잭션을 롤백하고 트랜잭션을 롤백해야 할 것입니다.

+0

유일한 문제는 Id를 기반으로 레코드가 업데이트되므로 사이트가 잘못되어 여전히 잘못된 레코드를 업데이트 할 수 있습니다. 사이트를 확인하는 유일한 방법은 데이터베이스에 메시지를 쿼리하고 사이트 ID를 확인한 다음 사용자가 액세스 할 수있는 사이트 ID와 비교하는 것입니다. 이것은 내가 피하려고했던 데이터베이스에 대한 추가 여행이 필요합니다. 복합 ID는 사이트 ID와 ID를 사용하도록 요구함으로써이 문제점을 수정합니다. 현재이 문제를 해결하기 위해 원시 SQL을 사용했지만 Update에 추가 기준을 추가 할 수 있기를 희망했습니다. –

+0

"사이트가 틀리거나 잘못된 레코드를 업데이트 할 수 있습니다." - 예를 들어 쓴 것과 비슷한 방법으로 업데이트를 수행하는 경우는 아닙니다. 로그인이 손상되면 공격자는 응용 프로그램에서 허용하는 작업 만 수행 할 수 있습니다. 응용 프로그램. 또는 서버가 침입하여 침입자가이 방법을 우회하거나 자신의 SQL을 작성할 수있는 경우 유일한 보호는 빈번한 백업입니다. –

+0

Jamie, 답변 해 주셔서 감사합니다. 내 원래의 질문에 대한 짧은 대답은 업데이트에 기준을 추가 할 수 없다는 것입니다. 예를 들어 데이터베이스의 원본 메시지를 쿼리하고 상태 필드를 업데이트 한 다음 사이트 ID를 그대로두고 사용자가 액세스 할 수있는 메시지와 현재 사이트로 MessageUpdate 메서드를 호출해야합니다. 이것은 확실히 작동하지만 네이티브 SQL을 사용하면 쿼리를 피하고 where 문을 사용하여 사용자 사이트 ID가 레코드의 사이트 ID와 일치하는지 확인할 수 있습니다. 레코드가 업데이트되지 않으면 다양한 작업을 수행 할 수 있습니다. –

관련 문제