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

时间:2019-07-29 21:19:21

标签: c# asp.net-core-2.2 ef-core-2.2 .net-core-2.2

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

  

{
  “ id”:“ 00000000-7357-000b-0001-000000000000”,
  “ tenantId”:“ 00000000-7357-000a-0001-000000000000”,
  “ userName”:“ user1”,
  “房客”:{
  “ id”:“ 00000000-7357-000a-0001-000000000000”,
  “ name”:“第一假组织”,
  “成员”:[

我这样配置了延迟加载。

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

如何更改代码,以免延迟加载的实体得到服务?我希望它只会向客户返回一个空列表。我是否应该为此使用DTO而不是像这样从数据库返回?有人在谈论完全不对here使用惰性加载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);
}

我不确定要搜索什么,我得到的所有匹配都指向UseLazyLoadingProxies()发票。

1 个答案:

答案 0 :(得分:2)

这可能会有点缠绵:但是,到此为止。

听起来您有一些看起来像这样的实体

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称为这些导航属性)。

如果您不需要Tenant属性,则可以省略.include语句。除非这意味着更通用(在这种情况下,更强烈的理由要使用其他模式和自动映射器)。

希望您的数据库并没有真正建立FK关系,如果确实如此,请尽快修复该问题。

下一个问题是您可能不需要子属性列表,但是它在模型中,因此它们将是“那里”。尽管您的列表租户可能是null。虽然这对您可能很好,但现在。通常,当我看到API返回属性时,我希望某些东西不存在(此成员没有租户)或某些问题,例如我可能错过了第二个参数。在93.284%的情况下,这可能不是问题,但这是要注意的。

这开始了解为什么AutoMapper很棒。您的数据库模型,业务模型和视图可能有所不同。而且,您不应该直接返回数据库模型。控制应用程序每个部分的数据表示方式是一个好主意。

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

[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的每次使用将如何映射。