@mr_blond97

Объект с полями (one-to-many) возвращается со значением null в полях в Entity Framework, как это решить?

Использую Entity Framework и SQLite.

Context:
public class WordContext : DbContext
{
    public DbSet<VmWord> Words { get; set; }
    public DbSet<LearnDay> LearnDay { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=db_name.db");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

Модели:
public class Word
{
    public int Id { get; set; }
    public IList<LearnDay> LearnDay { get; set; }
}

public class LearnDay
{
    public int Id { get; set; }
    public string Key { get; set; }
    public int Value { get; set; }
    public Word Word { get; set; }
}

Инициализация объекта:
using (var db = new WordContext())
{
    db.Words.Add(new VmWord
    {
        LearnDay = new List<LearnDay> 
                    {
                        new LearnDay {
                            Key = "pl",
                            Value = 0
                        },
                        new LearnDay {
                            Key = "en",
                            Value = 0
                        }
                    }
    });
    db.SaveChanges();
}


На этом шаге все работает, в таблицах сохраняются значения.

Но затем я получаю объект:
using (var db = new WordContext())
{
    // word != null и LearnDay == null
    var word = db.Words.Where(p => p.Id == testId).FirstOrDefault();
}


Поле LearnDay == null.

Но если сделать так:
I use Entity Framework and SQLite.

The context:

public class WordContext : DbContext
{
    public DbSet<VmWord> Words { get; set; }
    public DbSet<LearnDay> LearnDay { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=db_name.db");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}
The models:

public class Word
{
    public int Id { get; set; }
    public IList<LearnDay> LearnDay { get; set; }
}

public class LearnDay
{
    public int Id { get; set; }
    public string Key { get; set; }
    public int Value { get; set; }
    public Word Word { get; set; }
}
How I initialize and save object:

using (var db = new WordContext())
{
    db.Words.Add(new VmWord
    {
        LearnDay = new List<LearnDay> 
                    {
                        new LearnDay {
                            Key = "pl",
                            Value = 0
                        },
                        new LearnDay {
                            Key = "en",
                            Value = 0
                        }
                    }
    });
    db.SaveChanges();
}
At this steep it looks like it work ok, I open the db and check that tables contain this data.

But then I try to get object and it returns with:

LearnDay == null
using (var db = new WordContext())
{
    // word != null but LearnDay == null
    var word = db.Words.Where(p => p.Id == testId).FirstOrDefault();
}
And if I do:

using (var db = new WordContext())
{
    // learnDay != null
    // learnDay.Word !=null
    // even learnDay.Word.learnDay !=null
    var learnDay = db.LearnDay.Where(p => p.Word == testWord).FirstOrDefault();

    // then try again to get word:
    // word != null
    // LearnDay != null
    var word = db.Words.Where(p => p.Id == testId).FirstOrDefault();
}


И после этого шага поле Word.LearnDay != null.
  • Вопрос задан
  • 150 просмотров
Решения вопроса 1
@kttotto
пофиг на чем писать
Обратите внимание в документации EF на метод Include(), зачем он нужен и что он делает.
Если Вам нужно, чтобы при запросе Word, кроме данных самой сущности, еще подтянулись зависимые, нужно сделать так
var word = db.Words.Include(x => x.LearnDay).Where(p => p.Id == testId).FirstOrDefault();
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Какая версия EF?

В целом
public virtual ICollection<LearnDay> LearnDay { get; set; }
спасет, если не Core, т.к. реализовано lazy, в коре спасают инклюды
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы