Asp.net 我们什么时候需要数据类?

Asp.net 我们什么时候需要数据类?,asp.net,asp.net-mvc,asp.net-core,Asp.net,Asp.net Mvc,Asp.net Core,我使用asp.net内核。以下是将模型与控制器一起使用的基本方法 public class BookController : Controller { private readonly ApplicationDbContext _context { get; set; } public BookController(ApplicationDbContext context) { _context = context; } public

我使用asp.net内核。以下是将模型与控制器一起使用的基本方法

public class BookController : Controller
{
    private readonly ApplicationDbContext _context { get; set; }

    public BookController(ApplicationDbContext context)
    {
        _context = context;
    }

    public IActionResult Create(Book model)
    {
        // adding new model
    }

    public IActionResult Edit(Book model)
    {
        // modifying the model
    }

    public IActionResult Delete(Book model)
    {
        // removing the model
    }
}
我的问题:我应该/应该何时在控制器内实现代码?我应该/应该在什么时候在另一个课堂上实施它

大概是这样的:

public interface IBook
{
    int Add(Book book);

    int Update(Book book);

    int Remove(Book book);
}

public class BookData : IBook
{
    private readonly ApplicationDbContext _context { get; set; }

    BookData(ApplicationDbContext context)
    {
        _context = context
    }

    public int Add(Book model)
    {
        // ...

        return _context.SaveChanges();
    }

    // other implements...
}
然后,在控制器内部调用它:

public IActionResult Create(Book model)
{
    var bookData = new BookData(_context);
    int result = bookData.Add(model);

    // ...
}
对于接口,我认为它在这种情况下可能很有用:我有许多控制器需要相同的操作/方法名称

示例:
MessageController
至少需要3个操作/方法(
Create/Add
Edit/Update
Delete/Remove
)。它与
NotificationController
class、
CommentController
class相同

因此,可以将接口改进为:

public interface IMyService<T> where T : class
{
    int Add(T model);

    int Update(T model);

    int Remove(T model);
}

public class MyService<T> : IMyService<T> where T : class
{
    private readonly ApplicationDbContext _context { get; set; }

    public MyService(ApplicationDbContext context)
    {
        _context = context;
    }

    public int Add(T model)
    {
        Type type = typeof(model);

        if (type == typeof(Book))
        {
            // adding new book model
        }
        else if (type == typeof(Comment))
        {
            // adding new comment model
        }

        // ...

        return -1;
    }

    // other implements...
}
公共接口IMyService,其中T:class
{
int-Add(T型);
int更新(T模型);
int-Remove(T型);
}
公共类MyService:IMyService其中T:class
{
私有只读应用程序上下文{get;set;}
公共MyService(ApplicationDbContext上下文)
{
_上下文=上下文;
}
公共整数加法(T型)
{
类型=类型(型号);
如果(类型==类型(书籍))
{
//添加新书模型
}
else if(type==typeof(Comment))
{
//添加新的注释模型
}
// ...
返回-1;
}
//其他工具。。。
}

我误解了什么吗?

如果我用数据类正确地理解了它,那么实际上是指存储库(它是持久层上的抽象)。您应该始终将持久性逻辑封装在类后面(通过存储库模式、命令/查询模式或请求处理程序),并使用它,而不是直接使用服务类中的上下文

也就是说,您可以直接将
BookData
注入控制器,而不是
ApplicationDbContext
。在当前实现中,你应该考虑的一个问题是工作模式的单元。现在,每次添加都会立即保存数据

这可能不是您想要的,因此您应该移动
\u context.SaveChanges()
Add/Remove/Update
方法之外,并显式调用它。这允许您插入10条记录,如果其中一条记录失败,则不会将任何内容保留到数据库中

但是如果调用
\u context.SaveChanges()每次插入后,您在第8条(共10条)记录中得到一个错误,然后7条记录将被保留,3条记录将丢失,您将得到不一致的数据

控制器不应该包含任何逻辑,只对输入模型进行短期验证(
ModelState.IsValid
check),如果可以,调用执行所有逻辑的服务并将结果报告给用户。只有在非常简单的教程和指南中,出于简单的原因,逻辑才会被放入控制器操作中。在实际应用中,您永远不应该这样做。控制器比服务类更难进行单元测试