Entity Framework Core + MariaDB - свойство навигации имеет значение null - PullRequest
6 голосов
/ 14 мая 2019

У меня есть отношение многие ко многим, определенное с помощью таблицы в MariaDB. Я пытаюсь использовать свойства навигации в Entity Framework Core для связанных объектов, но они не гидратированы.

roles

| role_id | role_name |
| 1       |  Role-A   |
| 2       |  Role-B   |

groups

| group_id |  group_name |
|  1       |   Group-A   |
|  2       |   Group-B   |

role_to_group

|  role_to_group_id   |   role_id  | group_id |
|          1          |    1       |   1      |
|          2          |    2       |   1      |
|          3          |    2       |   2      |

Это класс

[Table(name: "role_to_group")]
public class RoleToGroup
{
    [Column(name: "role_to_group_id")]
    public long RoleToGroupId { get; set; }

    [Column(name: "role_id")]
    [ForeignKey("RGToRoles")]
    public int RoleId { get; set; }

    [Column(name: "group_id")]
    public int UserGroupId { get; set; }

    [Include]
    public Role Role { get; set; }
    [Include]
    public UserGroup UserGroup { get; set; }
}

[Include] - это пользовательский атрибут, предназначенный для гидратации свойств навигации с использованием шаблона, аналогичного DbContext.Set<T>().Include("property_name"), с помощью метода расширения, который отображает T и находит все свойства с атрибутом [Include], определенным для них.

Однако я не могу заставить это работать правильно. Свойства навигации Role и UserGroup возвращают ноль.

Что вы предлагаете, я делаю неправильно? Также, пожалуйста, дайте мне знать, если вам нужно больше деталей, чтобы добавить к вопросу !!

1 Ответ

0 голосов
/ 25 мая 2019

Возможно, проблема в том, что EF Core не выполняет автоматическую загрузку.( Документация о том, как реализовать отложенную загрузку ).

Когда установлены следующие пакеты NuGet:

  • Microsoft.EntityFrameworkCore.Proxies
  • Microsoft.EntityFrameworkCore.Relational

и включена отложенная загрузка, например:

    public class MyDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseMySQL(@"User Id=root;Host=localhost;Database=Test;");

            optionsBuilder
                .UseLazyLoadingProxies();
        }

        public DbSet<UserGroup> UserGroups { get; set; }
        public DbSet<Role> Roles { get; set; }
        public DbSet<RoleToGroup> RoleToGroups { get; set; }
    }

Я загрузил его:

        using (var context = new MyDbContext())
        {
            var roleGroup1 = context.RoleToGroups.First();
            Console.WriteLine(roleGroup1.Role.Name); //Role-A
            Console.WriteLine(roleGroup1.UserGroup.Name); //Group-A
        }

Ленивая загрузка требует, чтобы типы были общедоступными,и свойства для отложенной загрузки должны быть виртуальными:

[Table(name: "role_to_group")]
public class RoleToGroup
{
    [Column(name: "role_to_group_id")]
    public int RoleToGroupId { get; set; }

    [Column(name: "role_id")]
    [ForeignKey("roles")]
    public int RoleId { get; set; }

    [Column(name: "group_id")]
    [ForeignKey("groups")]
    public int UserGroupId { get; set; }

    public virtual Role Role { get; set; } //must be virtual
    public virtual UserGroup UserGroup { get; set; }//must be virtual
}

[Table(name: "roles")]
public class Role
{
    [Key]
    [Column(name: "role_id")]
    public int RoleId { get; set; }

    [Column(name: "role_name")]
    public string Name { get; set; }
}

[Table(name: "groups")]
public class UserGroup
{
    [Key]
    [Column(name: "group_id")]
    public int GroupId { get; set; }

    [Column(name: "group_name")]
    public string Name { get; set; }
}

В качестве альтернативы отложенной загрузке можно использовать ручную Eager или явную загрузку из того же doc .

...