gpt4 book ai didi

c# - EF Core - 无法访问 Select() 中的导航属性

转载 作者:太空宇宙 更新时间:2023-11-03 12:31:54 25 4
gpt4 key购买 nike

我正在尝试访问 IdentityUser 模型的导航角色属性。

在 GetQueryable 函数中我正在设置 include 属性

protected virtual IQueryable<TEntity> GetQueryable<TEntity>(
Expression<Func<TEntity, bool>> filter = null,
string includeProperties = null
)
where TEntity : class, IEntity
{
IQueryable<TEntity> query = context.Set<TEntity>();
if (filter != null)
{
query = query.Where(filter);
}

if (includeProperties != null)
{
query = query.Include(includeProperties);
}
return query;
}

如果我执行以下查询,则角色属性已成功填充:

return GetQueryable<ApplicationUser>(e => e.Id == id, "Roles").SingleOrDefault();

但是当我将投影(选择)与以下 Dto 一起使用时:

public class ApplicationUserDto: BaseDto
{
public string Email { get; set; }
public string Name { get; set; }
public List<IdentityUserRole<string>> Roles{ get; set; }

public static Expression<Func<ApplicationUser, ApplicationUserDto>> SelectProperties = (user) => new ApplicationUserDto {
Id = user.Id,
Email = user.Email,
Name = user.Name,
Roles = (List<IdentityUserRole<string>>)user.Roles
};
}

然后下面的查询崩溃了:

return GetQueryable<ApplicationUser>(e => e.Id == id, "Roles").Select(ApplicationUserDto.SelectProperties).SingleOrDefault();

错误如下:

System.InvalidOperationException: The type of navigation property 'Roles' on the entity type 'IdentityUser<string, IdentityUserClaim<string>, IdentityUserRole
<string>, IdentityUserLogin<string>>' is 'ICollection<IdentityUserRole<string>>' for which it was not possible to create a concrete instance. Either initialize the
property before use, add a public parameterless constructor to the type, or use a type which can be assigned a HashSet<> or List<>.

它还会记录一个警告:

warn: Microsoft.EntityFrameworkCore.Query.RelationalQueryCompilationContextFactory[6]
The Include operation for navigation: 'user.Roles' was ignored because the target navigation is not reachable in the final query results.

最佳答案

您需要具体化(执行子查询,这将显式收集角色)以便将其分配给您的 DTO:

public class ApplicationUserDto: BaseDto
{
public string Email { get; set; }
public string Name { get; set; }
public List<IdentityUserRole<string>> Roles{ get; set; }

public static Expression<Func<ApplicationUser, ApplicationUserDto>> SelectProperties = (user) => new ApplicationUserDto {
Id = user.Id,
Email = user.Email,
Name = user.Name,
Roles = user.Roles.ToList()
};
}

并记得添加:
使用 System.Linq;
到您的文件,以便能够在 ICollection 上调用 .ToList()

正如您在评论中所述,您想要的类型是一个字符串,因此您可以在 user.Roles 之后执行任何操作,即像这样执行进一步的投影:

user.Roles.Select(role=> role.RoleId).ToList()

请记住事后具体化结果。

关于c# - EF Core - 无法访问 Select() 中的导航属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42436197/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com