2014-01-17 1 views
3

저는 데이터베이스 우선 프로젝트를 수행하고 있습니다.사용자 지정 Microsoft.AspNet.Identity.EntityFramework.UserStore <TUser>

VS2013에 새로운 MVC5 사이트를 설치했습니다.

public class ApplicationUser : IdentityUser 
{ 
    public String EMail { get; set; } 
} 

은 그때 이미 생성되었던 AspNetUsers 테이블에 이메일 필드를 생성 :

나는 이메일 속성이있는 applicationUser를 만들었습니다. 그런 다음 Microsoft.AspNet.Identity.EntityFramework.UserStore에서 상속받은 도메인 별 사용자 저장소를 만들고 두 가지 기능, 즉 FindByEmail 및 FindByEmailAsync를 구현했습니다.

FindByEmail은 다음과 같습니다

public ApplicationUser FindByEMail(String email) 
{ 
    var context = base.Context; 

    String commandText = "Select * from AspNetUsers Where EMail = @email"; 
    var query = context.Database.SqlQuery(typeof(ApplicationUser), commandText,new SqlParameter("@email",email)); 
    var result = query.ToListAsync().Result.ToArray().GetValue(0); 
    return result as ApplicationUser; 
} 

내 단위 테스트는이 방법 녹색 실행하고 있습니다. 지금 비동기 메서드를 구현하고 작업 반환하려고합니다. Task ...를 통해 작업하고 ApplicationUser에 개체를 변환하지 않고이 작업을 수행하려고합니다. F #은 두뇌에서 Seq.Map (재미 u -> (ApplicationUser) u)을하고 싶습니다 .C#에 대한 equiv가 있습니까?

나는 올바른 방법으로 문제에 접근하고 있습니까? . MSDN의 예를 들어 내가 코드를 먼저 할 수 없기 때문에

답변

4

우선 해제, 동기 버전, 그것은 처음부터 비동기 호출을 방지하기 위해 더 나을 것이다 당신은 당신의 쿼리를 작성할 수로 :.

var query = context.Database.SqlQuery<ApplicationUser>(commandText, new SqlParameter("@email",email)); 
return query.First(); 

이렇게하면 "동기화를 통한 비동기 동기화"를 피할 수 있습니다 (ToListAsync() 다음에 Result 호출을 사용).

비동기 버전에 대한

, 당신은 단지 사용하십시오 :

public async Task<ApplicationUser> FindByEMailAsync(String email) 
{ 
    var context = base.Context; 

    String commandText = "Select * from AspNetUsers Where EMail = @email"; 
    var query = context.Database.SqlQuery<ApplicationUser>(commandText, new SqlParameter("@email",email)); 
    var data = await query.ToListAsync(); 
    return data.First(); 
} 
보조 노트에

:

내 머리의 F 번호가 Seq.Map을하고 싶어 (재미 U를 -> (응용 프로그램 사용자) u a. C#에 대한 equiv가 있습니까?

equivelent의 C#을 가능성이 특정 시나리오에서 더 적절할 것 a.Cast<ApplicationUser>().First()를 사용하여 있음을 의미하며, a.Select(u => (ApplicationUser)u);를 통해 Enumerable.Select을 사용하는 것입니다.

또 다른 측면 참고 : 이메일이 발견되지 않는 경우 그들은 당신이 항상 하나 개 일치하는 결과를 얻을 수 있습니다 가정하기 때문에

이 방법은 문제가 될 것입니다. First 대신 FirstOrDefaultAsync()FirstOrDefault()을 사용하고 null 응답을 확인하여 처리 할 수 ​​있습니다. 나는 의도적으로이 방법으로 쓰지 않았다. 원래 방법의 행동을 모방하려했는데 (던지기도하지만, 을 던지고 마음은 InvalidOperationException이된다.)

+0

동의한다 - 나는 그렇지 않았다. 아직 거기에 도착했다. 일치하지 않는 단위 테스트가 이미 시작되었습니다. 흥미롭지는 않지만 항상 인수를 확인하고 항상 반환 값을 확인합니다. 저렴한 보험. 8-) –

+0

first() 및 firstAsync()에서 죽어 가고 있습니다. 'System.Data.Entity.Infrastructure.DbRawSqlQuery '에는'First '에 대한 정의가없고'System.Data.Entity.Infrastructure.DbRawSqlQuery '형식의 첫 번째 인수를 수락하는'First '확장 메서드가 없습니다 (using 지시문이나 어셈블리 참조가 누락 되었습니까?). 나는 System.Linq를 사용하고있다. –

+0

@JamieDixon Edited - DbRawSqlQuery가 아니라 정상적인 DbSet이라고 생각했습니다. 원시 쿼리는 그 점에서 좋지 않습니다. –

관련 문제