如何从EF核心的相关数据中获取很少的属性?

这是ASP .net EF核心。

我有2节课。提名与用户具有一对多的关系。

提名将具有指向用户ID的外键。

课程:

public class Nomination
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int NominationId { get; set; }
    public int NomineeUserId { get; set; }
    public int NominationYear { get; set; }

    public User Nominee { get; set; }
}
public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailId { get; set; }
    public byte[] PasswordHash { get; set; }
    public byte[] PasswordSalt { get; set; }
}
public class UserDto
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

上下文:

protected override void OnmodelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasKey(x => x.UserId);
        modelBuilder.Entity<User>().Property(x => x.UserId).ValueGeneratedOnAdd();

        modelBuilder.Entity<Nomination>().HasKey(x => x.NominationId);
        modelBuilder.Entity<Nomination>().Property(x => x.NominationId).ValueGeneratedOnAdd();
        modelBuilder.Entity<Nomination>().HasOne(x => x.Nominee).WithMany().HasForeignKey(x => x.NomineeUserId).OnDelete(DeleteBehavior.Restrict);
    }

控制器GetaLL:

public async Task<actionResult<IEnumerable<Nomination>>> GetNomination()
    {
        return await _context.Nomination
            .Include(n => n.NominationDetails)
            .Include(n => n.Nominee)
            .ToListAsync();
    }

当我执行GetaLL for Namination时,我会收到“ Nominee”(用户)的完整对象,包括密码。 我需要UserDTO而不是User。我不需要用户的其他属性

我应该如何更改代码以实现此目的?

karl9413 回答:如何从EF核心的相关数据中获取很少的属性?

如果您不使用诸如AutoMapper之类的映射库,则可以使用LINQ选择并返回如下新类型:

假设我们也创建了一个NominationDto

NominationDto.cs

public class NominationDto
{
    public int NominationId { get; set; }
    public int NomineeUserId { get; set; }
    public int NominationYear { get; set; }
    public UserDto Nominee { get; set; }
}
var nominations = _context.Nomination
    .Include(n => n.NominationDetails)
    .Include(n => n.Nominee)
    .Select(nomination => new NominationDto
    {
        NominationId = nomination.NominationId,NomineeUserId = nomination.NomineeUserId,NominationYear = nomination.NominationYear,Nominee = new UserDto
        {
            UserId = nomination.Nominee.UserId,FirstName = nomination.Nominee.FirstName,LastName = nomination.Nominee.LastName
        }
    }).ToListAsync();

但是,如果可能的话,我建议使用AutoMapper或其他映射库。它将处理将NominationUser实体对象映射到NominationDtoUserDto对象。然后,您无需手动进行操作。

(我尚未测试上面的代码,但是我认为应该可以将您放在一个不错的位置。)

编辑 在对原始答案发表评论后,我更新了上面代码的LINQ部分。

,

.Select()之前使用LINQ的.ToListAsync()函数编写一个选择投影。

这将创建一个SQL查询以仅获取您在LINQ中选择的那些DB列。

例如提名Dto

public class NominationDto
{
    public int NominationId { get; set; }
    public int NomineeUserId { get; set; }
    public int NominationYear { get; set; }
    public UserDto Nominee { get; set; }
}

您的查询可能是:

var nominations = await _context.Nomination
        .Include(n => n.NominationDetails)
        .Include(n => n.Nominee)
        .Select(nomination => new NominationDto
    {
        NominationId = nomination.NominationId,LastName = nomination.Nominee.LastName
        }
    }).ToListAsync();

请注意,您可能不需要.Include(n => n.NominationDetails),因为在此查询中,没有从NominationDetails中获取/选择/投影任何内容。

此外,如果您不打算跟踪这些实体的变化,则可以在.Select()之后和.ToListAsync()之前使用.AsNoTracking()的方法来告诉EF,您将获得更好的性能,以获得更好的性能跟踪EF对象图中检索到的数据的变化。

您可以在此处找到有关查询跟踪的更多信息:https://docs.microsoft.com/en-us/ef/core/querying/tracking

本文链接:https://www.f2er.com/3027909.html

大家都在问