Почему отношения один-ко-многим дают мне ноль (Entity Framework)? - PullRequest
0 голосов
/ 13 июня 2019

У меня следующий контекст базы данных приложения:

public class ApplicationContext : DbContext
{
    private readonly string _connectionString;

    public ApplicationContext(IConfiguration configuration)
    {
        _connectionString = configuration.GetConnectionString("Recipes");
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Recipe> Recipes { get; set; }
    public DbSet<Ingredient> Ingridients { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseNpgsql(_connectionString);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Ingredient>()
            .HasOne(x => x.Recipe)
            .WithMany(y => y.Ingredients);
    }
}

Моя бизнес-модель проста: в одном рецепте много ингредиентов, а в одном ингредиенте только одна квитанция.

Модели

Рецепт:

public class Recipe
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public List<Ingredient> Ingredients { get; set; }

    public DateTime CreatedAt { get; set; }

    public DateTime UpdatedAt { get; set; }

    public Recipe()
    {
        CreatedAt = DateTime.UtcNow;
        UpdatedAt = DateTime.UtcNow;
    }
}

Ингредиент

public class Ingredient
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public int ClientId { get; set; }

    public string Name { get; set; }

    public decimal Count { get; set; }

    public string Measure { get; set; }

    public int Number { get; set; }  

    public DateTime CreatedAt { get; set; }

    public DateTime UpdatedAt { get; set; }

    public Recipe Recipe { get; set; }

    public Ingredient()
    {
        CreatedAt = DateTime.UtcNow;
        UpdatedAt = DateTime.UtcNow;
    }
}

И здесь я пытаюсь получить коллекцию ингредиентов из рецепта:

List<Recipe> recipes;


recipes = _applicationContext.Recipes.Where(r => r.Category.ClientId == id).ToList();

Но ингредиенты всегданоль.Я не понимаю почему.Вот результат:

enter image description here

Что не так?

Ответы [ 3 ]

2 голосов
/ 13 июня 2019

Вам необходимо включить дочерние свойства в запрос, иначе вы получите от них нулевое значение.Это сделано для обеспечения высокой производительности с Entity Framework.Если бы все дочерние свойства были автоматически включены, в sql-запросах, которые генерирует EF, может быть сгенерировано много ненужных объединений, что может привести к значительному снижению производительности (и в этом случае у нас, вероятно, будет .Exclude метод расширения!)

т.е.:

List<Recipe> recipes = _applicationContext.Recipes.Include(x => x.Ingredients).Where(r => r.Category.ClientId == id).ToList();

1 голос
/ 13 июня 2019

Если вы хотите, чтобы в свойствах навигации была указана Ленивая загрузка, я думаю, вам нужно сделать их виртуальными.

public virtual ICollection<Ingredient> Ingredients { get; set; }

Или вы можете включить их в свой запрос, чтобы они выбирались одновременно с получателями.

recipesWithIngredients = _applicationContext.Recipes
    .Include(r => r.Ingredients)
    .Where(r => r.Category.ClientId == id)
    .ToList();
1 голос
/ 13 июня 2019

В дополнение к тому, что сказал @GregH, вы можете пометить Ingredients как virtual, чтобы их можно было загружать лениво.

public class Recipe
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public virtual List<Ingredient> Ingredients { get; set; } // marked as virtual

    public DateTime CreatedAt { get; set; }

    public DateTime UpdatedAt { get; set; }

    public Recipe()
    {
        CreatedAt = DateTime.UtcNow;
        UpdatedAt = DateTime.UtcNow;
    }
}

Теперь вы можете либо загружать их так, как описано в принятом ответе, либо загружать их лениво, как вы пытались сделать это раньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...