2012-06-14 4 views
0

에있는 경우 내 데이터베이스에서 같은 테이블이 이러한 사용자의 등 Customer, Member, Instructor, Employee 각처럼 자신의 이메일 adrress 있습니다. 주어진 이메일을 가진 사용자가 이미 있는지 확인해야합니다. 이 같은확인 값이 여러 테이블

  • 확인 각 테이블에 뭔가를 : 나는 생각했다
public bool IsEmailAddressExists(string email) 
    { 
     if (!Context.Customers.Any(c => string.Equals(c.Email, email, StringComparison.InvariantCultureIgnoreCase))) 
      if (!Context.Members.Any(m => string.Equals(m.Email, email, StringComparison.InvariantCultureIgnoreCase))) 
       ... 
    } 
  • 모든 이메일을 선택하고 확인 :
public bool IsEmailAddressExists(string email) 
    { 
     var emails = Context.Customers.Select(c => c.Email).Union(Context.Members.Select(m => m.Email))...; //other unions 
     return emails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase)); 
    } 

더 테이블이 있고 많은 사용자들, 그런 종류를 구현하는 가장 효율적인 방법이 무엇인지 알고 싶습니다. 확인 중.

감사합니다.

+0

'선택'을하지 않으면 '임의'가 더 효율적입니다. 그러나 각 테이블을 검색 할 때마다 더 많은 옵션을 볼 수 없습니다. 추가 성능 비트가 실제로 필요한 경우 스토어드 프로 시저와 동일하게 수행 할 수 있습니다. 대안은 아마도 하나의 테이블에 모든 이메일 주소를 저장하고 관계를 연결하는 것입니다 (훨씬 더 많은 일이 있습니다). – musefan

+0

@musefan, 답변 해 주셔서 감사합니다. 나는 두 옵션에 대해 생각했다. 저장 프로 시저와 개별 전자 메일 테이블에 대해 생각할 것입니다. 데이터베이스 스키마를 변경할 수 없습니다. – Zabavsky

답변

1

을 순수 SQL 이것은 당신의 가장 효율적인 것 그것이 일치에 도달하는 즉시 검색을 중단하기 때문에 :

... 저장 프로 시저로 :

CREATE PROCEDURE EmailExists 
    @email varchar(254) = NULL 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    DECLARE @emailExists bit 

    SET @emailExists = 0 

    SELECT @emailExists = 1 WHERE EXISTS(SELECT 1 FROM Customer WHERE email = @email) 
    IF @emailExists = 0 
    BEGIN 
     SELECT @emailExists = 1 WHERE EXISTS(SELECT 1 FROM Member WHERE email = @email) 
     IF @emailExists = 0 
     BEGIN 
      SELECT @emailExists = 1 WHERE EXISTS(SELECT 1 FROM Instructor WHERE email = @email) 
      IF @emailExists = 0 
      BEGIN 
       SELECT @emailExists = 1 WHERE EXISTS(SELECT 1 FROM Employee WHERE email = @email) 
      END 
     END 
    END 

    SELECT @emailExists 
END 

... 스칼라 반환 함수로 :

CREATE FUNCTION EmailExists 
(
    @email varchar(254) 
) 
RETURNS bit 
AS 
BEGIN 
    DECLARE @emailExists bit 

    SET @emailExists = 0 

    SELECT @emailExists = 1 WHERE EXISTS(SELECT 1 FROM Customer WHERE email = @email) 
    IF @emailExists = 0 
    BEGIN 
     SELECT @emailExists = 1 WHERE EXISTS(SELECT 1 FROM Member WHERE email = @email) 
     IF @emailExists = 0 
     BEGIN 
      SELECT @emailExists = 1 WHERE EXISTS(SELECT 1 FROM Instructor WHERE email = @email) 
      IF @emailExists = 0 
      BEGIN 
       SELECT @emailExists = 1 WHERE EXISTS(SELECT 1 FROM Employee WHERE email = @email) 
      END 
     END 
    END 

    -- Return the result of the function 
    RETURN @emailExists 
END 

Linq에와 C#에서, 당신은 어떤 확장 및하여 사용할 수 있습니다 || 운영자. Any는 보통 SQL에서 EXISTS로 변환되고 || C#의 연산자가 게으른 경우 전자 메일의 첫 번째 발생에 도달하면 바로 평가가 중지됩니다.

bool emailExists = customerEmails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase)) 
        || memberEmails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase)) 
        || instructorEmails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase)) 
        || employeeEmails.Any(e => string.Equals(e, email, StringComparison.InvariantCultureIgnoreCase)); 
+0

감사합니다. JamieSee. 지금은 두 번째 접근법을 사용 하겠지만, 앞으로는 'FUNCTION'을 만들 것입니다. – Zabavsky

5

두 가지 옵션이있는 것 같습니다.

보기 만들기. 전자 메일 주소 만 보여주는보기를 데이터베이스에 만들 수 있습니다. 그 이메일이 이미 존재하는지 당신이 이메일의 목록을 확인할 수 있도록 해당 뷰에 바인딩 엔티티를 사용하여 ...

CREATE VIEW EmailView AS 
SELECT Email from Customers 
UNION ALL 
SELECT Email from Instructors 
.... 

: 당신은 MSSQL 서버, 같은를 사용하는 가정. 자세한 내용은 documentation을 확인하십시오.

데이터베이스를 표준화하십시오.이 테이블 각각은 전자 메일 이외의 일반적인 정보, 예를 들어 이름 및/또는 성을 공유합니까? "Persons"테이블에 해당 정보를 넣고 다른 테이블을 외부 테이블에 배치하기 위해 데이터 모델을 재구성하는 것이 좋습니다. (이 또한 사용자가 고객 및 강사 다른 두 가지가 있습니다 말한다면 도움이 될 것입니다.)

+2

Bah, 전 커피입니다. 저장 프로 시저를 사용하여 약간의 결과를 얻을 수도 있습니다. – Ross

+0

감사합니다. 로스.예, 성과 이름과 같은 공통 정보가 있지만 위에서 말했듯이 데이터베이스 스키마는 변경할 수 없습니다. – Zabavsky