2014-09-23 3 views
1

내가 NHibernate에 (3.3.3-SP1)을 통해 매핑 된 데이터베이스 테이블을 가지고

상황없이. 응용 프로그램은 .NET4.0에서 실행되며 매핑은 FluentNHibernate (1.4.0)를 통해 수행됩니다.NHibernate에 될 saveOrUpdate 기본 키

CREATE TABLE Movies 
(id INT PRIMARY KEY, 
yearPublished DATETIME NOT NULL, 
name NVARCHAR(500) NOT NULL, 
description NTEXT NOT NULL) 

데이터는 다음과 같이 될 것이다 :

 
id | yearPublished | name     | description 
---+---------------+------------------------+-------------------------------------------- 
1 | 1968   | 2001: A Space Oddyssey | An epic drama of adventure and exploration 

문제점 내가이 테이블의 새로운 엔티티를 생성하고 같은 현실에 대해 둘 이상의 개체를 추가하지 않으려 해요

세상 일. Session.SaveOrUpdate이 있다는 것을 알고 있으며 복합 및 자연 id로 작동하도록 만드는 방법도 있지만 사실 엔 엔티티가 기본 키를 실제로 가지고 있기 때문에 원하는 것이 아니며 실제로는 기본 키가 없기 때문에 합성 키가 필요합니다. 중복이 DB에 있습니다.

var movie = new Movies 
{ 
    yearPublished = 1968, 
    name = "2001: A Space Oddyssey", 
    description = "An awesome journey to Jupiter" 
}; 

// Behavior right now: 

// Adds a new movie besides the fact that 
// the movie is already in the database 
// but now has two entries 
session.SaveOrUpdate(movie); 

Assert.IsTrue(movie.id == 2 && movie.description == "An awesome journey to Jupiter"); 

// What I really want is to be able to define what 
// makes an object unique other than the primary key; 
// in this scenario it should look for a combination 
// of "yearPublished" and "name" 
session.MyAwesomeSaveOrUpdate(movie); 

Assert.IsTrue(movie.id == 1 && movie.description == "An epic drama of adventure and exploration"); 

(예를 들어 커스텀 매핑을 통해) NHibernate에있는 장소에서이 기능 아니면 내가 DB에서 후보자를 가져가 그것을 손으로해야합니까?

감사합니다.

답변

0

데이터베이스의 자연 키 필드에 고유 제한 조건을 추가하고 예외 변환기를 사용하여 SQL Server 예외를 응용 프로그램에서 처리 할 수있는 것으로 변환합니다.

public class SqlServerExceptionConverter : ISQLExceptionConverter 
{ 
    public Exception Convert(AdoExceptionContextInfo adoExceptionContextInfo) 
    { 
     var sqlException = adoExceptionContextInfo.SqlException as SqlException; 
     if (sqlException != null) 
     { 
      // 2601 is unique key, 2627 is unique index; same thing: 
      // http://blog.sqlauthority.com/2007/04/26/sql-server-difference-between-unique-index-vs-unique-constraint/ 
      if (sqlException.Number == 2601 || sqlException.Number == 2627) 
      { 
       // my custom exception 
       return new UniqueKeyException(sqlException.Message, sqlException); 
      } 
     } 
     return adoExceptionContextInfo.SqlException; 
    } 
} 

내가 생각할 수있는 또 다른 방법은 삽입 전에 일치하는 레코드에 대한 데이터베이스를 조회 할 수 있지만 레코드가 선택하고 삽입 사이에 삽입 될 수 있기 때문에 그 고장이 아니다.

+0

저는 제어 흐름에 예외를 사용하는 팬이 아니지만 적어도 작동하는 것으로 보입니다. 비록 DIY 방법을 사용하고 있습니다 만 – mfeineis

+1

데이터베이스 예외를 처리하려면 다른 옵션이 없습니다. 데이터를 미리 확인하거나 where 절을 포함시키지 않고 예외를 잡아 내고 응용 프로그램에서 처리 할 수있는 무언가로 변환하면 오류를 피할 수 있습니다. –