我有两个类Note和User,而我的Users有Notes。在我的User类中,连接是通过Notes列表进行的,而在我的数据库中是通过Notes表中的UserID列进行的,因此当我在DbSet中添加Notes时,UserID值始终为null。通过DbSet添加时,如何使UserId获取用户的ID。
public class Note
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Text { get; set; }
public Note(string title, string text)
{
Title = title;
Text = text;
}
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
[MaxLength(30)]
public string Username { get; set; }
[Required]
[MaxLength(30)]
public string Password { get; set; }
public ICollection<Note> Notes { get; set; }
public User(string username, string password)
{
Username = username;
Password = password;
Notes = new List<Note>();
}
}
public void AddNote(Note currentNote)
{
currentUser.Notes.Add(currentNote);
DBContext.Notes.Add(currentNote);
DBContext.SaveChanges();
}
答案 0 :(得分:0)
虽然EF可以自动计算出关系,但是通常最好了解如何明确地将它们映射出来,以便您处理情况不太正确的情况。这可以通过DbContext上的OnModelCreating重写或使用DbContext加载的EntityTypeConfiguration<TEntity>
类来完成。
例如,使用OnModelCreating :(假定注释的用户是必需的,但是注释没有用户参考)
// EF 6
modelBuilder.Entity<User>()
.HasMany(x => x.Notes)
.WithRequired()
.Map(x => x.MapKey("UserId"));
// EF Core
modelBuilder.Entity<User>()
.HasMany(x => x.Notes)
.WithOne()
.IsRequired()
.HasForeignKey("UserId");
这些操作是为了建立关系以在Notes表上使用UserId,而无需在Notes实体上声明UserId或User引用。
在您的示例中,当您调用AddNote时,不清楚“ currentUser”来自何处。正确设置关系后,EF将自动分配所有必需的FK。需要注意的是,您需要确保从相同的DbContext加载实体。我看到的一个潜在问题是DbContext变量的作用域。上下文应该是短暂的,因此应避免使用诸如静态甚至私有成员变量之类的方法,因为您要确保在不需要上下文时将其丢弃。为安全起见,应将用户从与要将Note保存到相同的DbContext中拉出,并且应避免将实体传递到其DbContext范围之外。传递DTO或ViewModels(POCO非实体类)或相关数据,但在上下文范围内加载/创建实体,不要让它们离开它。
public void AddNote(NoteViewModel currentNote)
{
using(var context = new MyDBContext())
{
var currentUser = context.Users.Single(x => x.UserId = currentUserId);
var note = new Note
{
Text = currentNote.Text,
// ... other stuff.
};
currentUser.Notes.Add(currentNote);
context.SaveChanges();
}
}