无法在 EF Core 2.2 中配置延迟加载以切断未加载的部分

Can't configure lazy loading in EF Core 2.2 to cut off unloaded parts

我在调用 API 时得到以下内容。当成员链接到的租户实体将开始列出其成员实体时,它会在中间中断。

{
"id":"00000000-7357-000b-0001-000000000000",
"tenantId":"00000000-7357-000a-0001-000000000000",
"userName":"user1",
"tenant":{
"id":"00000000-7357-000a-0001-000000000000",
"name":"First Fake Org",
"members":[

懒加载我是这样配置的

services.AddDbContext<Context>(config => config
  .UseLazyLoadingProxies()
  .UseSqlServer(Configuration.GetConnectionString("Register")));

我应该如何更改代码以使延迟加载的实体无法得到服务?我希望它只是 return 给客户端的一个空列表。我应该为此目的使用 DTO 而不是像这样从数据库中使用 return 吗?有人说 API 完全不使用延迟加载

[HttpGet("test1/{username}"), AllowAnonymous]
public IActionResult GetStuff(string userName)
{
  Member output;

  output = Context.Members
    .Include(e => e.Tenant)
    .Single(e => e.UserName == userName);

  return Ok(output);
}

我不确定要 google 做什么,我得到的所有点击都指向 UseLazyLoadingProxies() 调用。

这可能会有些冗长:但这里是。

听起来您的实体看起来像:

public partial class Member
{
   public virtual long Id { get; set; }
   public virtual List<Tenant> Tenants { get; set; }  //tables have fk relationship
}


 public partial class Tenant
{
   public virtual long Id { get; set; }
   public virtual List<Member> Members{ get; set; }  //tables have another fk relationship?
}

然后对于这个方法:

[HttpGet("test1/{username}"), AllowAnonymous]
public IActionResult GetStuff(string userName)
{
  Member output;

  output = Context.Members
    .Include(e => e.Tenant)
    .Single(e => e.UserName == userName);

  return Ok(output);
}

我看到了一些问题,但我会尽量简短:

我不会让控制器直接执行此操作。但它应该有效。

我认为您忽略了 .Include 语句的作用。当对象被实例化时,它将获得所有这些相关的实体。 Includes 实质上将您的 where 语句转换为左连接,其中外键匹配(EF 调用这些导航属性)。

如果您不想要租户属性,那么您可以省略.Include 语句。除非这意味着更通用(在这种情况下,更有理由使用不同的模式和自动映射器)。

希望您的数据库没有真正的双向 FK 关系,如果有,请尽快修复。

下一个问题是您可能不需要子属性列表,但它在模型中,因此它们将是 "there"。尽管您的 List Tenants 可能是 null。虽然这对你来说可能没问题,但现在。作为一般规则,当我看到一个 API return 一个 属性 时,我希望某些东西不存在(该成员没有租户)或者有问题,比如我错过了第二个参数。这在 93.284% 的情况下可能不是问题,但需要注意这一点。

这开始解释为什么 AutoMapper 很棒。您的数据库模型、业务模型和视图可能不同。尽管您不应该 return 直接对数据库建模。控制应用程序每个部分的数据表示方式是个好主意。

您可以轻松地减少代码,并删除导航属性:

[HttpGet("test1/{username}"), AllowAnonymous]
public IActionResult GetStuff(string userName)
{   
  return Ok(Context.Members
    .Include(e => e.Tenant)
    .Single(e => e.UserName == userName));    
}

但同样,业务层会更好:

[HttpGet("test1/{username}"), AllowAnonymous]
public IActionResult GetStuff(string userName)
{
  return Ok(MemberRepository.GetMember(userName));
}

不过,我要强调的重点是创建视图模型。

例如,假设用户详细信息:

public class MemberDetail
{
   public string UserName {get; set;}
   public long UserId { get; set; }
   public string FullName { get; set; }
}

这样视图总是接收到您想要看到的内容,而不是额外的数据。添加这一点,你可以确切地知道每次使用 MemberMemberDetail 将如何映射。