2014-01-17 18 views
3

我是一個在做數據庫優先項目。custom Microsoft.AspNet.Identity.EntityFramework.UserStore <TUser>

我在VS2013中創建了一個新的MVC5站點。

我創建了具有電子郵件財產applicationUser:

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

我那麼在已經創建的AspNetUsers表創建一個電子郵件字段。然後,我創建了一個特定於域的用戶存儲,它繼承自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; 
} 

我的單元測試運行綠化用這種方法。我現在試圖實現異步方法並返回一個任務。我試圖做到這一點,而不是......通過任務來完成任務,並將對象聚合到ApplicationUser。我的大腦中的F#想要做一個Seq.Map(fun u - >(ApplicationUser)u a。是否有一個相當於C#?

我是否正確地接近問題的正確方法?我受到限制,無法遵循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(樂趣û - >(ApplicationUser)u a。有沒有C#的equiv?

的equivelent C#是通過a.Select(u => (ApplicationUser)u);使用Enumerable.Select話雖這麼說,使用a.Cast<ApplicationUser>().First()很可能會在這種特定情況下更合適。

另一個側面說明:

這些方法是有問題的,如果沒有找到該郵件,因爲他們認爲您總能獲得一個匹配結果。您可以通過使用FirstOrDefaultAsync()FirstOrDefault()而不是First,並檢查空響應。我故意沒有這樣寫,因爲我試圖模仿你原來的方法的行爲(這也將拋出,雖然你拋出一個IndexOutOfRangeException,並且心智會提高InvalidOperationException。)

+0

我同意 - 我沒有到那裏了。我有非匹配單元測試已經開始....我可能不會很有趣,但我總是驗證我的論點,並總是檢查我的返回值。廉價保險。 8-) –

+0

它正在死於第一個()和firstAsync()。 「System.Data.Entity.Infrastructure。DbRawSqlQuery'不包含'First'的定義,並且沒有找到接受'System.Data.Entity.Infrastructure.DbRawSqlQuery'類型的第一個參數的擴展方法'First'(你缺少using指令還是程序集引用? )。我有一個使用System.Linq; –

+0

@JamieDixon編輯 - 我認爲這是一個普通的'DbSet',而不是'DbRawSqlQuery' - 原始查詢在這方面不太好。 –