我正在做一个数据库优先的项目。
我在 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;
}
使用此方法我的单元测试运行正常。我现在正在尝试实现异步方法并返回一个任务。我正在尝试在没有 for..eaching 任务并将对象转换为 ApplicationUser 的情况下执行此操作。我脑子里的 F# 想做一个 Seq.Map(fun u -> (ApplicationUser)u a. C# 有等价物吗?
我是否以正确的方式解决问题?我受限,无法遵循 MSDN 的示例,因为我无法做到代码优先。
最佳答案
首先,对于同步版本,最好首先避免异步调用。您可以将查询写成:
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();
}
旁注:
The F# in my brain wants to do a Seq.Map(fun u -> (ApplicationUser)u a. Is there an equiv for C#?
等效的 C# 将使用 Enumerable.Select
通过a.Select(u => (ApplicationUser)u);
也就是说,使用 a.Cast<ApplicationUser>().First()
在这种特定情况下可能更合适。
另一个旁注:
如果找不到电子邮件,这些方法就会出现问题,因为它们假设您总是会得到一个匹配的结果。您可以使用 FirstOrDefaultAsync()
来处理它和 FirstOrDefault()
而不是 First
,并检查空响应。我故意没有这样写,因为我试图模仿你原来方法的行为(它也会抛出,虽然你的抛出 IndexOutOfRangeException
,并且头脑会提高 InvalidOperationException
。)
关于c# - 自定义 Microsoft.AspNet.Identity.EntityFramework.UserStore<TUser>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21176012/