我正在尝试从标准MVC注册表单(即电子邮件字段)插入一个值,这将是另一个表中的主键和FK。我的学生表只包含电子邮件,我想插入在注册时提交给aspnetusers表的相同值(电子邮件字段)。到目前为止我编写了这段代码:
var student = new Student { email = model.Email };
分配值然后
db.Students.Add(student);
db.SaveChanges();
执行操作,我假设这是在注册控制器中完成的。请告知我是否把它放在错误的部分。我目前正在接受
请参阅以下代码:
AccountController.cs
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var student = new Student { email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
string callbackUrl = await SendEmailConfirmationTokenAsync(user.Id, "Confirm your account");
ViewBag.Message = "Check your email and confirm your account, you must be confirmed "
+ "before you can log in.";
db.Students.Add(student);
db.SaveChanges();
return View("Info");
//return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
Student.cs
public class Student
{
[Key, ForeignKey("User")]
public string email { get; set; }
public virtual ApplicationUser User { get; set; }
}
答案 0 :(得分:2)
此处的外键位于隐式表colum User_Id
上,默认情况下为不可为空,并且您没有为User
设置值以从中获取值。看起来你想要将电子邮件用作外键,但事实并非如此。外键引用相关表的主键,AspNetUsers
为Id
,不 Email
。即使你可以这样做,这也是一个非常糟糕的主意。 Email
是NVARCHAR(MAX),无法编入索引。
简而言之,快速解决方法是在学生实例上设置User
:
var student = new Student { email = model.Email, User = user };
但是,在这里实现继承会好得多。学生是用户,所以按照这样设置:
public class Student : ApplicationUser
然后,你完全不需要这些。通过创建Student
会自动生成关联的ApplicationUser
,因为 是ApplicationUser
。
<强>更新强>
继承时,请记住您继承了ApplicationUser
上的所有属性,因此您无需再次添加Email
等。如果您从上下文中提取用户,则可以使用OfType<Student>
仅限学生。如果您使用ApplicationUserManager
的默认实现,它将始终返回ApplicationUser
个实例。但是,由于它继承自UserManager<TUser>
,因此您只需修改该类以保持通用:
public class ApplicationUserManager<TUser> : UserManager<TUser>
where TUser : ApplicationUser
为了避免修改任何现有代码,您也可以声明该类的非泛型版本:
public class ApplicationUserManager : ApplicationUserManager<ApplicationUser>
{
public ApplicationUserManager(UserStore<ApplicationUser> store)
: base(store)
{
}
}
然后,您可以构建ApplicationUserManager
的不同实例,以便与您拥有的不同类型的用户一起工作。由于ApplicationUser
是您的基本类型,因此如果您需要使用所有用户,则应使用该类型,例如为了进行常规登录。
答案 1 :(得分:0)
如果student.email是FK,则必须在db中存在电子邮件才能添加新学生
答案 2 :(得分:0)
Student.cs不正确。 外键指向另一个表中的PRIMARY KEY。
您可以像这样编辑Student.cs:
public class Student
{
[Key]
public int StudentId { get; set; }
//Foreign key for User
[ForeignKey("User")]
public int UserId { get; set; }
public virtual ApplicationUser User { get; set; }
}
如果电子邮件是唯一的,请在注册时在用户表上进行检查:
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var checkEMail = db.AspNetUsers.Where(a=>a.Email == model.Email).FirstOrDefault();
if(checkEMail != null)
{
//Email is not valid
}
else
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var student = new Student { email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
string callbackUrl = await SendEmailConfirmationTokenAsync(user.Id, "Confirm your account");
ViewBag.Message = "Check your email and confirm your account, you must be confirmed "
+ "before you can log in.";
db.Students.Add(student);
db.SaveChanges();
return View("Info");
//return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
}