gpt4 book ai didi

c# - AutoMapper 在 IQueryable 上调用 ProjectTo() 时抛出 StackOverflowException

转载 作者:IT王子 更新时间:2023-10-29 04:42:03 25 4
gpt4 key购买 nike

我使用 EF Code First 创建了具有彼此集合的类。实体:

public class Field
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<AppUser> Teachers { get; set; }
public Field()
{
Teachers = new List<AppUser>();
}
}

public class AppUser
{
public int Id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string UserName => Email;
public virtual List<Field> Fields { get; set; }
public AppUser()
{
Fields = new List<FieldDTO>();
}
}

DTO:

public class FieldDTO
{
public int Id { get; set; }
public string Name { get; set; }
public List<AppUserDTO> Teachers { get; set; }
public FieldDTO()
{
Teachers = new List<AppUserDTO>();
}
}

public class AppUserDTO
{
public int Id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string UserName => Email;
public List<FieldDTO> Fields { get; set; }
public AppUserDTO()
{
Fields = new List<FieldDTO>();
}
}

映射:

Mapper.CreateMap<Field, FieldDTO>();
Mapper.CreateMap<FieldDTO, Field>();
Mapper.CreateMap<AppUserDTO, AppUser>();
Mapper.CreateMap<AppUser, AppUserDTO>();

调用此代码时出现 StackOverflowException(上下文是我的 dbContext):

protected override IQueryable<FieldDTO> GetQueryable()
{
IQueryable<Field> query = Context.Fields;
return query.ProjectTo<FieldDTO>();//exception thrown here
}

我猜这是因为它在列表中循环,无休止地互相调用。但我不明白为什么会这样。我的映射有误吗?

最佳答案

您有自引用实体和自引用 DTO。一般来说,自引用 DTO 不是一个好主意。尤其是在进行投影时 - EF 不知道如何将项目的层次结构连接在一起。

你有两个选择。

首先,您可以通过明确地为 DTO 建模并考虑层次结构来强制特定深度的层次结构:

public class FieldDTO
{
public int Id { get; set; }
public string Name { get; set; }
public List<TeacherDTO> Teachers { get; set; }
public FieldDTO()
{
Teachers = new List<TeacherDTO>();
}
}

public class TeacherDTO
{
public int Id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string UserName => Email;
}

public class AppUserDTO : TeacherDTO
{
public List<FieldDTO> Fields { get; set; }
public AppUserDTO()
{
Fields = new List<FieldDTO>();
}
}

这是首选方式,因为它最明显和明确。

不太明显、不太明确的方法是将 AutoMapper 配置为具有遍历层次关系的最大深度:

CreateMap<AppUser, AppUserDTO>().MaxDepth(3);

我更喜欢#1,因为它最容易理解,但#2 也可以。

关于c# - AutoMapper 在 IQueryable 上调用 ProjectTo<T>() 时抛出 StackOverflowException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37251043/

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