[我有一个使用ASP.NET Identity 2.2的Entity Framework应用程序(即,我的上下文继承自IdentityDbContext<T>
,并且我有一个User
类继承自IdentityUser
)。我已经在我的seed方法中使用以下调用成功为AspNetUsers
表添加了种子:
var testUser = new User() {
UserName = "TestUser",
Email = "[email protected]"
};
manager.Create(testUser, "TestPassword");
我已将模型扩展为包括Post
类,其中包括对我的User
类的引用:
public class Post {
public Post() {}
[Required]
public int Id { get; set; }
[Required]
public User User { get; set; }
}
并且,当然,这对应于我的User
类中的以下内容:
public class User : IdentityUser {
public User() : base() {
this.Posts = new HashSet<Post>();
}
public ICollection<Post> Posts { get; set; }
//Additional members...
}
然后我将以下内容植入Posts
集合:
var testPost = new Post() { Id = 1, User = testUser };
context.Posts.AddOrUpdate(
post => post.Id,
testPost
);
从技术上讲,这很好;将创建Post
实例,并使用新创建的User_Id
实例的Id
正确填充自动生成的User
字段。
那么怎么了?每次运行时,我都会在EntityValidationErrors
中得到以下内容:“用户字段为必填”。它不会阻止我的应用程序正常运行,但是很难检测到合法错误。
[显然,我可以向DbContext.SaveChanges()
方法中添加自定义代码以忽略此错误,但是我宁愿理解为什么它首先发生,特别是如果我如何播种数据时出现问题。
似乎在调用UserManager.Create()
方法时,它不会使用创建引用所需的信息来更新User
实例。我的假设是它没有填充Id
字段,但我尚未确认。
无论如何,解决方案是在调用UserManager.Create()
之后重新加载用户。我的最终代码如下:
var manager = new UserManager<User>(new UserStore<User>(context));
var testUser = new User() {
UserName = "TestUser",
Email = "[email protected]"
};
if (manager.Users.Count<User>() == 0) {
manager.Create(testUser, "TestPassword");
}
testUser = (User)manager
.Users
.Where<User>(u => u.UserName == "TestUser")
.FirstOrDefault<User>();
然后我就可以像以前一样播种Post
记录:
var testPost = new Post() { Id = 1, User = testUser };
context.Posts.AddOrUpdate(
post => post.Id,
testPost
);
注:如果使用
[ForeignKey]
属性,显然有必要通过User
(例如Id
)而不是通过对象引用(例如UserId = testUser.Id
)来分配User = testUser
。
在我的实际应用程序中,所有这些都改组为CreateUser()
辅助方法,因此可以轻松创建多个测试用户,但这涵盖了基础知识。这也解决了我的原始代码中的一个缺陷,即以前我没有检查以确定用户是否已经创建。