自定义Microsoft.AspNet.Identity.EntityFramework.UserStore <tuser> </tuser>

时间:2014-01-17 01:02:30

标签: c# async-await

我是一个数据库优先项目。

我在VS2013中创建了一个新的MVC5站点。

我创建了一个具有电子邮件属性的applicationUser:

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

然后我在AspNetUsers表中创建了一个已经创建的EMail字段。然后我创建了一个特定于域的用户存储,它继承自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(有趣的你 - >(ApplicationUser)你是。是否有C#的等价物?

我是否以正确的方式解决问题?我受到限制,无法遵循MSDN的示例,因为我无法执行代码优先。

1 个答案:

答案 0 :(得分: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)你是。是否有C#的等价物?

平等的C#将通过Enumerable.Select使用a.Select(u => (ApplicationUser)u);。话虽如此,在这种特定情况下使用a.Cast<ApplicationUser>().First()可能会更合适。

另一方面说明:

如果找不到电子邮件,这些方法会有问题,因为他们假设您总是会得到一个匹配的结果。您可以使用FirstOrDefaultAsync()FirstOrDefault()代替First来处理此问题,并检查空响应。我故意没有这样写,因为我试图模仿原始方法的行为(虽然你的方法会引发IndexOutOfRangeException,但也会引发InvalidOperationException。)