c# - ASP.NET Web API 2 CRUD 操作与实体框架
问题描述
我正在创建一个 MS Web API 2 项目。我在一个单独的项目中创建了我的实体框架,并在我的 API 中引用它。阅读了一些教程,建议:
“理想情况下,我们不应该从 Web API 返回 EF 实体对象。建议从 Web API 返回 DTO(数据传输对象)”。
因此,我在我的 API 中创建了我的模型:
namespace MyAPI.Models
{
[Table("Customer")]
public class CustomerViewModel
{
[Key]
public int CustomerID { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
}
我的问题是:我需要为我的 API 中的每个模型创建一个数据上下文类还是可以使用 EF 上下文类?如果我确实需要为每个模型创建一个单独的上下文,我如何通过引用 EF 上下文类来实现这一点?以下是我开始的内容:
namespace MyAPI.Models
{
public class CustomerDbContext : DbContext
{
public CustomerDbContext() : base("name=CusetomerDbContext")
{
}
public DbSet<MyEFDataAccess.Customer> CustomerViewModel { get; set; }
}
}
我的控制器是:
namespace MyAPI.Controllers
{
public class CustomersController : ApiController
{
private readonly CustomerDbContext _context = new CustomerDbContext();
// GET: api/Customer
public IQueryable<CustomerViewModel> GetCustomerViewModels()
{
return _context.CustomerViewModel;
}
}
以上正确抛出错误,因为它不能直接将 EF 客户转换为 CustomerViewModel!
解决方案
理想情况下,我们不应该从 Web API 返回 EF 实体对象。建议从 Web API 返回 DTO(数据传输对象)。
这样做的原因是确保您可以在不更改 API 的情况下更改数据库架构,反之亦然。如果你实现了这个目标,那么你就已经遵守了给定的建议。
你遇到的问题是基本的。TypeA
不能隐式转换为 Type B
。就编译器而言,您正在尝试将 a 转换DbContext
为 a FormControl
,但它不知道如何做到这一点。您需要明确告诉它要做什么。一个例子,虽然不是很好:
public DbSet<MyEFDataAccess.Customer> Customer { get; set; }
和
public IQueryable<CustomerViewModel> GetCustomerViewModels()
{
return _context.Customer.Select(
customer => new CustomerViewModel
{
// <assign properties here>
}
);
}
话虽这么说,IQueryable<T>
从控制器返回一个绝对是禁忌。您肯定希望允许消费者查询特定记录。您可以这样做以启用分页,例如:
public async Task<List<CustomerViewModel>> GetCustomerViewModels(
int skip = 0,
int take = 100
)
{
return await _context.Customer
.Skip(skip)
.Take(take)
.Select(
customer => new CustomerViewModel
{
// <assign properties here>
}
)
.ToListAsync();
}
推荐阅读
- kubernetes - Rancher:能够获取,但不能创建对象( dial tcp [::1]:6443: connect: network is unreachable)
- c++ - length() 函数返回不正确的值,而如果在 C++ 的主函数中实现相同的逻辑,它是否正确?
- css - 如何手动将 Faux Bold 应用于特定字体文件(.ttf)以生成新字体文件(.ttf)
- apache-spark - Big Query 无法将字符串转换为时间戳
- kotlin - 是否可以复制 KClass 并更改其属性?
- debugging - 如何调试 woocommerce 覆盖的文件夹
- scala - 如何从 Source 或 Flow 中的元素生成物化值?
- java - 在Java中存储货币双倍(浮点),没有任何数学,总是准确的吗?
- php - 如何从 htaccess 的重写条件中排除子文件夹规则
- typescript - 打字稿:动态检查第二个参数键在第一个参数上不存在