我想问一些有关asp.net mvc5的问题。我现在正在编写一个中级(对我来说肯定是:D)应用程序。我想得到什么,我有什么问题?
我创建了一个基本的MVC页面,并从asp.net模板进行了注册和登录。现在,我想用我的想法扩展此页面。
首先:我要添加新实体,该实体将具有其他表(例如,来自AspNetUser)的外键。当我需要来自表AspNetUser的外键用户ID时,如何将数据推入数据库? -我认为在模型类中,我必须在ApplicationUser类中添加公共ApplicationUser用户{get; set;}和ICollection myModels {get; set;},然后在控制器中,我的Action必须获取所有参数(包括外键),但是接下来是什么?如何从表AspNetUser获取用户ID?请给我一个这个想法的基本例子吗?
第二:什么更好?代码优先还是数据库优先?
请帮帮我。这对我来说很重要,因为没有这个我就不会毕业。
答案 0 :(得分:0)
您必须查看EntityValidationErrors
内的内容以找出到底出了什么问题,如果我不得不猜测,那么我认为这与您的ApplicationUser
类中的这一行有关:
public ICollection<TaskModel> TaskModels { get; set; }
首先,您应该使用virtual
关键字标记此属性以启用延迟加载。
然后,您需要在Entity Framework中配置此一对多关系。您可以通过在OnModelCreating
中覆盖OtherDbContext
方法,然后像这样配置关系来实现:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ApplicationUser>()
.HasMany(e => e.TaskModel)
.WithRequired(e => e.ApplicationUser)
.WillCascadeOnDelete(false);
}
但是,除非计划使用TaskModels
集合,否则您实际上并不需要它,因此您可以完全删除该集合,这样就可以解决问题。
顺便说一句,我个人更喜欢这样实现我的外键关系:
[ForeignKey(nameof(User))]
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
这样,我的外键引用不是一个魔术字符串,它就位于Navigation属性旁边。我发现它更干净,更安全。
我没有测试任何代码,但希望我没看错:-)
答案 1 :(得分:0)
所以..我创建了一个新项目,并再次做了。即使没有OnModelCreating和虚拟属性,它也可以工作。我不知道出什么问题了,但是我想这与数据库有关-我的意思是迁移等。
针对所有遇到相同问题的人:
只需将虚拟属性添加到我们的新模型类中(在此之前,您必须决定要使用什么关系;)),然后在IdentityModel.cs中将另一个虚拟属性添加到类ApplicationUser中,并记住使用正确的DbContext:)< / p>
感谢大家的帮助,祝您有愉快的一天!!
答案 2 :(得分:-1)
对不起,您是对的。所以我想将AspNetUsers(Id)的PK作为其他表的外键-TaskModel。我所做的:
TaskModel.cs类
public class TaskModel
{
[Required]
[Key]
public string Id { get; set; }
[Required]
public string Description { get; set; }
public string Status { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
public ApplicationUser ApplicationUser { get; set; }
}
IdentityModel.cs类
public class ApplicationUser : IdentityUser
{
public ICollection<TaskModel> TaskModels { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
public class OtherDbContext : IdentityDbContext
{
public DbSet<TaskModel> TaskModels { get; set; }
public OtherDbContext() : base("DefaultConnection") { }
public static OtherDbContext Create()
{
return new OtherDbContext();
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
以及控制器中的操作:
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult AddTask(TaskModel task)
{
using (var db = new OtherDbContext())
{
var Task1 = new TaskModel
{
Description = task.Description,
Status = task.Status,
UserId = User.Identity.GetUserId();
};
db.TaskModels.Add(Task1);
db.SaveChanges();
}
return View();
}
我得到一个错误:
System.Data.Entity.Validation.DbEntityValidationException:“对一个或多个实体的验证失败。有关更多详细信息,请参见“ EntityValidationErrors”属性。
我在做什么错了?