Установка значения в БД через EF, потому что это не в наших моделях - PullRequest
0 голосов
/ 31 марта 2019

У меня есть два класса Note и User, и у моих пользователей есть Notes.В моем классе User соединение осуществляется через Список заметок, но в моей БД через столбец UserID в таблице Notes, поэтому при добавлении Notes в мой DbSet значение UserID всегда равно нулю.Как сделать UserId для получения идентификатора пользователя при добавлении через DbSet.

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 голосов
/ 01 апреля 2019

Несмотря на то, что EF может автоматически определять отношения, обычно неплохо понять, как их явно отображать, чтобы вы могли справиться с ситуациями, когда это не совсем правильно. Это можно сделать с помощью переопределения OnModelCreating в DbContext или с помощью EntityTypeConfiguration<TEntity> классов, загружаемых DbContext.

Например, с помощью 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");

То, что они делают, это устанавливает отношение для использования UserId в таблице Notes без необходимости объявления UserId или ссылки на пользователя в сущности Notes.

Из вашего примера неясно, откуда появляется «currentUser» при вызове AddNote. Когда отношения установлены правильно, EF назначит все необходимые FK автоматически. Предостережение заключается в том, что вам необходимо убедиться, что объекты были загружены из одного и того же DbContext. Одна потенциальная проблема, которую я вижу, - это область видимости для вашей переменной DbContext. Контексты должны быть недолговечными, поэтому следует избегать таких вещей, как статические или даже закрытые переменные-члены, так как вы хотите обеспечить удаление контекстов, когда они не нужны. Чтобы быть в безопасности, пользователь должен быть извлечен из того же 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();
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...