调用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()
发票。
答案 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; }
}
这样,视图始终会准确地接收您要查看的内容,而不是多余的数据。加上这一事实,您就可以确切知道Member
到MemberDetail
的每次使用将如何映射。