通过EF在数据库中设置值,因为它不在我们的模型中

时间:2019-03-31 17:54:46

标签: c# sql-server entity-framework

我有两个类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();
        }

1 个答案:

答案 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();
        }
    }