无法在 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; }
}
这样视图总是接收到您想要看到的内容,而不是额外的数据。添加这一点,你可以确切地知道每次使用 Member
到 MemberDetail
将如何映射。
我在调用 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; }
}
这样视图总是接收到您想要看到的内容,而不是额外的数据。添加这一点,你可以确切地知道每次使用 Member
到 MemberDetail
将如何映射。