C# 控制器返回数据列表而不是单个项目,如何解决此问题?
背景 最近我换了工作,加入了一个WebAPI项目。我熟悉Web API和MVC的概念,但没有实际操作经验 我遵循了一些教程,并在此基础上通过Visual Studio 2017创建了一个空的WebApi项目,从数据库连接了我的模型并添加了控制器 这是修改后的控制器:C# 控制器返回数据列表而不是单个项目,如何解决此问题?,c#,asp.net-mvc,entity-framework,asp.net-web-api2,C#,Asp.net Mvc,Entity Framework,Asp.net Web Api2,背景 最近我换了工作,加入了一个WebAPI项目。我熟悉Web API和MVC的概念,但没有实际操作经验 我遵循了一些教程,并在此基础上通过Visual Studio 2017创建了一个空的WebApi项目,从数据库连接了我的模型并添加了控制器 这是修改后的控制器: private MyEntities db = new MyEntities(); //... [ResponseType(typeof(MyEntityType))] [Route("api/MyE
private MyEntities db = new MyEntities();
//...
[ResponseType(typeof(MyEntityType))]
[Route("api/MyEntity")]
public async Task<IHttpActionResult> GetMyEntityType([FromUri]int parameter)
{
MyEntityType found = db.MyEntity
.OrderByDescending(c => c.CreationTime)
.First(c => c.ParameterColumn == parameter);
if (found == null)
{
return NotFound();
}
return Ok(found );
}
如果您使用的是Entity Framework Core 2,请尝试以下操作:
MyEntityType found = await db.MyEntity.AsNoTracking()
.OrderByDescending(c => c.CreationTime)
.FirstOrDefaultAsync(c => c.ParameterColumn == parameter);
最好通过依赖项注入来包含数据库上下文,而不是使用私有字段。如果您使用的是Entity Framework Core 2,请尝试以下方法:
MyEntityType found = await db.MyEntity.AsNoTracking()
.OrderByDescending(c => c.CreationTime)
.FirstOrDefaultAsync(c => c.ParameterColumn == parameter);
最好通过依赖项注入包含数据库上下文,而不是私有字段。当MyEntityType实例通过
Ok
返回时,它将转换为JSON,JSON将读取所有公共属性和字段的值。这将导致EF加载整个实体和所有关系。如果您只需要返回特定的属性,请按如下所示使用Select()
var found = db.MyEntity
.OrderByDescending(c => c.CreationTime)
.Select(c => new { c.CreationTime, c.ParameterColumn })
.First(c => c.ParameterColumn == parameter);
您可以根据需要定制选定的特性。如果在First()中需要不需要选择的条件,请将条件移动到Select之前的Where()调用中
var found = db.MyEntity
.OrderByDescending(c => c.CreationTime)
.Where(c => c.ParameterColumn == parameter)
.Select(c => new { c.CreationTime })
.First();
您可能应该创建MyEntityType的ViewModel,该ViewModel只具有所需的属性,并将这些属性映射到ViewModel的新实例。然后还可以更新[ResponseType(typeof(MyEntityType))]
属性
例如,声明:
public class MyEntityTypeViewModel {
public DateTime CreationTime { get; set; }
public int ParameterColumn { get; set; }
}
然后在控制器操作中:
MyEntityTypeViewModel found = db.MyEntity
.OrderByDescending(c => c.CreationTime)
.Where(c => c.ParameterColumn == parameter)
.Select(c => new MyEntityTypeViewModel {
CreationTime = c.CreationTime,
ParameterColumn = c.ParameterColumn })
.First();
当MyEntityType实例通过
Ok
返回时,它将转换为JSON,JSON将读取所有公共属性和字段的值。这将导致EF加载整个实体和所有关系。如果您只需要返回特定的属性,请按如下所示使用Select()
var found = db.MyEntity
.OrderByDescending(c => c.CreationTime)
.Select(c => new { c.CreationTime, c.ParameterColumn })
.First(c => c.ParameterColumn == parameter);
您可以根据需要定制选定的特性。如果在First()中需要不需要选择的条件,请将条件移动到Select之前的Where()调用中
var found = db.MyEntity
.OrderByDescending(c => c.CreationTime)
.Where(c => c.ParameterColumn == parameter)
.Select(c => new { c.CreationTime })
.First();
您可能应该创建MyEntityType的ViewModel,该ViewModel只具有所需的属性,并将这些属性映射到ViewModel的新实例。然后还可以更新[ResponseType(typeof(MyEntityType))]
属性
例如,声明:
public class MyEntityTypeViewModel {
public DateTime CreationTime { get; set; }
public int ParameterColumn { get; set; }
}
然后在控制器操作中:
MyEntityTypeViewModel found = db.MyEntity
.OrderByDescending(c => c.CreationTime)
.Where(c => c.ParameterColumn == parameter)
.Select(c => new MyEntityTypeViewModel {
CreationTime = c.CreationTime,
ParameterColumn = c.ParameterColumn })
.First();
您显示的代码似乎没有被您的请求命中。检查另一个类似的函数,该函数返回整个列表并将其包含在您的问题中。您能否在问题中发布,您如何调用此方法?我不明白,根据你发布的内容,你是如何得到一份返回的列表的。是的,这一切对我来说也很好。我们可以看到客户端如何调用您的API吗?@KirkLarkin我在问题中解释道:我可以确认正在使用此方法。@raidensan我总是显式地关闭延迟加载,以便无意的枚举抛出错误,而不是导致返回大量不需要的数据。它使我避免了许多潜在的问题,也避免了显式地
。包括导航属性的轻微成本。您显示的代码似乎没有被您的请求击中。检查另一个类似的函数,该函数返回整个列表并将其包含在您的问题中。您能否在问题中发布,您如何调用此方法?我不明白,根据你发布的内容,你是如何得到一份返回的列表的。是的,这一切对我来说也很好。我们可以看到客户端如何调用您的API吗?@KirkLarkin我在问题中解释道:我可以确认正在使用此方法。@raidensan我总是显式地关闭延迟加载,以便无意的枚举抛出错误,而不是导致返回大量不需要的数据。它使我避免了许多潜在的问题,也避免了显式地。包括导航属性的轻微成本。