当我的“预订”表中没有任何内容时,我的“客户”和“住宿”表的GET端点运行正常。创建预订后,每个表的每个获取请求都会返回每个表的每个条目。 这是我的数据模型
这是我对客户的要求
// GET: api/Customer
[ResponseType(typeof(Customer))]
public async Task<IHttpActionResult> GetCUSTOMERs()
{
var customers = await db.Customers.ToListAsync();
return Ok(customers);
}
当我致电客户表获取请求时,我只想要客户数据,我该怎么做?
答案 0 :(得分:1)
实体框架模型默认情况下启用了延迟加载。
当您return Ok(customers);
时,API会尝试序列化实体,以便可以(可能)以JSON或XML的形式发送它们。在通过每个客户实体进行序列化时,它将遇到Bookings
属性。当序列化程序请求该属性时,实体框架将“延迟加载”与客户关联的预订。然后,序列化程序将尝试序列化每个预订并点击Accommodations
属性...,依此类推。
您的上面的代码返回了所有客户,因此您最终将返回所有已预订的住宿。我希望如果您创建了一个没有预订的新Accommodation
,它将不会在此调用的输出中返回。
有几种方法可以防止所有这些事情发生:
禁用延迟加载
您可以通过打开模型来禁用EF模型上的延迟加载,右键单击模型图的白色背景并选择“属性”,然后将“启用延迟加载”设置为“ False”。
如果要从实体访问相关属性的其他功能,则可以使用“包含”将它们加载到上下文中,也可以单独加载它们,然后让EF修补程序将实体连接在一起。
我的个人观点是,禁用延迟加载通常是一个好主意,因为它使您可以考虑对数据库的查询,并且必须更加明确地询问应返回哪些数据。但是,这可能会花费更多的精力,并且可能是您开始尝试优化应用程序而不是使其正常工作时要考虑的事情。
此Microsoft页面“ Loading Related Entities”还介绍了各种选项(并准确描述了延迟加载整个数据库的问题!)。
映射实体并返回DTO
如果将实体从EF映射到DTO,则可以更好地控制代码如何遍历模型。
从API角度来看,使用DTO是一个好主意,因为它允许您或多或少地定义端点(如接口)的输出。当基础数据结构可能更改时,这通常可以保持不变。返回EF模型的输出意味着,如果模型发生更改,则使用该数据的内容也可能需要更改。
诸如AutoMapper之类的东西通常用于将EF实体映射到DTO中。
序列化器设置
可能会有一些媒体类型格式化程序设置,这些设置使您可以限制要进行序列化的实体的深度。请参阅JSON and XML Serialization in ASP.NET Web API作为开始的地方。
这可能是一个太大的更改,并且当您想实际返回相关对象时,就会在此处引起问题。