Объект имеет значение null при настройке отношений один к одному с помощью Fluent API.

У меня есть три класса: Role, Permission и RolePermission (разрешение роли — это третья таблица в отношении многие ко многим)

public class Role : Entity
{
    public string Name { get; set; }
    public string Description { get; set; }
    public virtual ICollection<RolePermission> RolePermissions { get; set; }
}

public class Permission : Entity
{
    public string Name { get; set; }
    public virtual ICollection<RolePermission> RolePermissions { get; set; }
}

public class RolePermission : Entity
{
    public int RoleId { get; set; }
    public int PermissionId { get; set; }
    public Permission Permission { get; set; }
    public Role Role { get; set; }
}

Затем я использовал fluentAPI для настройки отношения:

Для Role:

HasMany(role => role.RolePermissions)
            .WithRequired(rolePermission => rolePermission.Role)
            .HasForeignKey(rolePermission => rolePermission.RoleId);

Для Permission:

HasMany(permission => permission.RolePermissions)
            .WithRequired(rolePermission => rolePermission.Permission)
            .HasForeignKey(rolePermission => rolePermission.PermissionId);

Для RolePermission:

HasRequired(rolePermission => rolePermission.Permission)
            .WithMany(permission => permission.RolePermissions)
            .HasForeignKey(rolePermission => rolePermission.PermissionId);

HasRequired(rolePermission => rolePermission.Role)
            .WithMany(role => role.RolePermissions)
            .HasForeignKey(rolePermission => rolePermission.RoleId);

Проблема в том, что заполняется только Role объект.

введите здесь описание изображения


person Mihai Alexandru-Ionut    schedule 10.09.2018    source источник
comment
Код в этом вопросе относится к установлению отношений. Сообщенная проблема в этом вопросе связана с тем, что связанные данные не загружаются автоматически. Это две разные вещи, мало связанные друг с другом. Покажите нам код, откуда вы запускаете свой запрос. Вы где-то пропустили Include? Вы обращались (и, следовательно, лениво загружали) к навигационной опоре Role, но не к опорной навигационной панели Permission? Я хотел бы увидеть код, начинающийся с того места, где вы запускаете запрос, до места, где вы проверяете этот объект (согласно вашему снимку экрана)   -  person Flater    schedule 10.09.2018
comment
@Flater, это запрос: var user = _userRepository.FirstOrDefaultAsync(us => us.Email == email); var userPermissions = user.UserRoles.First().Role.RolePermissions.Select(rp => rp.Permission).ToList();   -  person Mihai Alexandru-Ionut    schedule 10.09.2018
comment
@Flater, да, я должен использовать include, и проблема решена. Это решение, поэтому, пожалуйста, опубликуйте его как ответ, чтобы принять его.   -  person Mihai Alexandru-Ionut    schedule 10.09.2018


Ответы (2)


Код в этом вопросе относится к установлению отношений. Сообщенная проблема в этом вопросе связана с тем, что связанные данные не загружаются автоматически. Это две разные вещи, которые мало связаны друг с другом.
Вы где-то пропустили включение? Вы обращались (и, следовательно, лениво загружали) к навигационной опоре Role, но не к опорной навигационной панели Permission? Я хотел бы увидеть код, начинающийся с того места, где вы запускаете запрос, до места, где вы проверяете этот объект (согласно вашему снимку экрана)

Вы ответили запрошенным кодом:

var user = _userRepository
                .FirstOrDefaultAsync(us => us.Email == email); 

var userPermissions = 
           user.UserRoles
               .First()
               .Role
               .RolePermissions
               .Select(rp => rp.Permission)
               .ToList();

Если вы вставите в свой запрос оператор Include(), вы увидите, что Permission на самом деле будут получены правильно.

Я не совсем уверен, какой объект вы инспектируете. Скриншот говорит мне, что вы смотрите на RolePermission, но опубликованный код предполагает, что вы получаете список объектов Permission.

Несмотря на это, вы, кажется, уже исправили это, используя Include:

Mihai Alexandru-Ionut @Flater, да, я должен использовать include, и проблема решена. Это решение, поэтому, пожалуйста, опубликуйте его как ответ, чтобы принять его.

person Flater    schedule 10.09.2018

Свойство Id отсутствует как для таблиц Role, так и для таблиц Permission. Когда вы произносите свойство RoleId в таблице RolePermission, EF ищет свойство Id в таблице Role.

Обновите таблицы ролей и разрешений следующим образом и попробуйте:

public class Role : Entity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public virtual ICollection<RolePermission> RolePermissions { get; set; }
}

public class Permission : Entity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<RolePermission> RolePermissions { get; set; }
}
person Kailash Ravuri    schedule 10.09.2018
comment
Role наследует класс Entity, в котором есть виртуальный член с именем Id. Я забыл упомянуть об этом. - person Mihai Alexandru-Ionut; 10.09.2018