2009-10-24 5 views
1

나는 NHibernate의 Identifier를 으로 사용하는 곳을 한 곳 이상 읽었습니다. id가 서버 측에서 생성되었으므로 기본 키는 나쁜 습관으로 간주됩니다. 그러므로 서버에 대한 응답이 필요합니다. 생성 된 ID. 이의 내가 아주 간단한 도메인 모델이 있다고 가정 해 보자, 지금NHibernate Identifier Identity Generator 사용

을 (나는 또한 MS-SQL 서버 식별자를 생성 문제가있을 수 있으며,이 기본 키 위반을 일으킬 수 있다고 Ayende에 의해 게시물을 본 생각) : 블로그 및 게시물. 모든 블로그 많은 게시물을 가질 수 있고 각 게시물은 정확히 한 블로그 (한 많은 관계) 에 속하는 하지만 우리는 단지 포스트 SAVE 곳 -> 블로그 관계가 아닌 블로그 -> 게시물

지금

내가 사용하는 가정을 NHibernate에 함께 Idenitifer 아이디 생성 등의 난 그래서 내가 이런 내 C# 코드 뭔가가 계단식을 사용하지 않는 것이 :

지금 SaveBlogInTransaction(blog1);
SavePostsInTransaction(blog1posts);


, 내 질문은 이것이다 : 삽입이 한 장소에서만 할 수 있으면 내 코드 (동시성 문제는 없습니다), 게시물의 'th DB에 eir 블로그가 유효할까요?
PostId, PostName, PostType, BlogId

이는 BlogId이 유효 할 것이라는 점을 보장 할 수 있습니다 :


난의이 게시물 '테이블 스키마를 살펴 보자 의미?

참고 : 각 방법은 트랜잭션으로하고 그것이 그것은 당신의 매핑에 따라 달라 dB

답변

2

다시 게시 한 질문에서도 정확한 블로그 ID를 갖게됩니다. NHibernate는 Save가 호출되자 마자 데이터베이스 행에 Blog 행을 삽입하고 그 시간에 SCOPE_IDENTITY를 사용하여 생성 된 신원 값을 검색합니다. 이 ID 값은 블로그 개체에 저장되며 나중에 생성 된 모든 게시물에서 사용할 수 있습니다.

사람들은 신원 기반 ID가 좋은 선택이 아니라고 말합니다 - NHibernate는 올바른 신원 값을 얻을 수 있도록 행을 즉시 삽입하기 위해 SQL을 실행해야합니다. 만약 different identity generator이 사용되면, NHibernate는 객체 ID의 값을 결정하기 위해 데이터베이스에 접속할 필요가 없기 때문에 트랜잭션이 커밋 될 때까지 SQL insert 문을 실행하지 않을 수있다.

+0

나는 다른 생성기 전략을 사용하여 NHibernate가 삽입 된 ID를 얻기 위해 데이터베이스를 질의 할 필요가 없기 때문에 더 효과적인 trasnsaction을 할 것이라고 Sean과 동의한다. –

-1

저지 않습니다 끝에서 작동합니다. 블로그에 BlogPosts 콜렉션이 있고 BlogPost에 Blog에 대한 참조가있는 일대 다 관계를 매핑 한 경우 블로그를 만들고 BlogPosts 컬렉션에 게시물을 추가하고 블로그 만 저장할 수 있습니다. NHibernate는 먼저 블로그 레코드를 삽입하고 나서 그들을 유지하기 전에 자식 객체에 외래 키를 설정합니다. 이는 BlogId가 유효 함을 보증합니다.

나는 NHibernate 소스 코드를 보지 못했지만, 아마도 SCOPE_IDENTITY 이후에 ID를 검색하기 위해 모범 사례를 사용한다고 확신한다. This blog post에서는 세 가지 방법에 대해 설명합니다.

신원 사용은 나쁜 습관이라는 것에 동의하지 않습니다. 그것의 주된 문제는 Hibernate가 Flush가 호출되기 전에 객체를 유지할 수 있다는 것이다. 따라서 삽입이 트랜잭션 외부에서 발생할 수 있으며 레코드를 수동으로 삭제해야합니다.

+0

BlogPosts 테이블이 필요하지 않습니다. 각 블로그에 연결된 블로그 ( ) 만 저장하기 때문입니다. 나는 도메인 모델에서 일대 다 관계가 이지만 데이터베이스에는 없습니다 ... db의 게시물 항목에 유효한 blogid가 있는지 여부를 묻는 질문이 있습니다. 서버에서 응답을받지 못했습니다. 이전에 삽입 한 블로그의 ID는 무엇입니까? –

+0

BlogId는 어떻게 생성됩니까? 나는 당신의 질문을 이해할 지 모르겠다. 그러나 대답은 "아니오"라고 생각한다. 데이터베이스에 FK 관계가 없으면 유효한 BlogId를 보장 할 수 없습니다. –

+0

나는 외래 키를 가지고있다. 나는 실제로 성 - 활동 기록을 사용한다. 포스트 클래스에서 나는 블로그 타입의 프로퍼티를 가지고있다. (하지만 블로그 클래스에서는 포스트에 대한 언급이 없다.). 지금은 내 질문에 다시 물어 보는 방식을 보았습니다. 처음에는 더 많은 블로그를 삽입 한 다음 모든 게시물을 삽입했습니다. 괜찮습니까? 나는 SCOPE_IDENTITY가 여기에 사용되지 않아야한다고 생각한다. 왜냐하면 나는 하나 이상의 블로그를 삽입하기 때문이다. 각 게시물과 관련된 blogid에 버그가있을 수 있습니까? –

0

조금 다른 질문을하고 싶습니다.


SaveBlogInTransaction(blog1);
SaveBlogInTransaction(blog2);
SavePostsInTransaction(post1_a, post1_b, ...); // all the posts of blog1
SavePostsInTransaction(post2_a, post2_b, ...); // all the posts of blog2

가 그 post1_a, post1_b, ... 포스트 'blogid = blog1id을 보장 : 의 우리가이 코드를 가지고 있다고 가정 해 봅시다?
post2_a, post2_b, ... posts 'blogid = blog2id가 보장 되나요?

나는 우리가 처음 blog1, blog2 만 다음 blog1_posts 및 blog2_posts

메모 삽입하기 때문에 SCOPE_IDENTITY()가 여기에 맞지 않는 생각 : 우리가 모델의 여러 관계에 있지만, DB를 우리에 하나가를 각 게시물에 대해서만 저장 블로그에 속한 블로그의 ID입니다 (BlogPosts 테이블이 없음).