13

我正在学习 asp.net mvc,并通过了一个很好的教程来演示它。本教程还使用了实体框架。

我们有自己的数据访问类,我必须使用它。对于我需要做些什么来弥合我们的类和 MVC 框架之间的差距,我有点困惑。例如,在教程中,在 MovieController.cs 文件中,有一个 Edit 方法,如下所示:

[HttpPost]
        public ActionResult Edit(Movie movie)
        {
            if (ModelState.IsValid)
            {
                db.Entry(movie).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(movie);
        }

如果我不使用实体框架,它会是什么样子?我是否仍需要使用 ModelState.IsValid 并像完成状态一样保存状态

db.Entry(movie).State = EntityState.Modified;

请指教。在不使用实体框架的情况下使用 asp.net mvc 的清晰书面示例会很棒。

我需要知道的是状态在这里扮演什么角色以及它是强制使用还是只是实体框架运行方式的一部分。

我会将其重写为:

[HttpPost]
public ActionResult Edit(Movie movie)
{
    myDBObject.SaveChanges();
    return RedirectToAction("Index");

}

其中 myDBObject 是我的自定义数据库访问对象。

4

4 回答 4

20

您看到的控制器直接使用某些数据访问框架(例如实体框架)的示例是不好的示例。整个互联网都被这些东西污染了。我几乎看不到它,我的眼睛会受伤。我认为这些都是不好的做法。数据访问应在存储库中分离和抽象。例如:

public interface IMoviesRepository
{
    Movie Get(int id);
    void Save(Movie movie);
}

那么你可以使用普通的 ADO.NET、EF、NHibernate、远程 Web 服务调用、一些自定义 ORM 或其他任何东西来实现这个接口:

public class MyCustomFrameworkMoviesRepository: IMoviesRepository
{
    ...
}

控制器会将此存储库接口作为构造函数参数:

public class MoviesController: Controller
{
    private readonly IMoviesRepository _repository;
    public MoviesController(IMoviesRepository repository)
    {
        _repository = repository;
    }

    public ActionResult Index(int id)
    {
        var movie = _repository.Get(id);
        return View(movie);
    }

    [HttpPost]
    public ActionResult Index(Movie movie)
    {
        if (!ModelState.IsValid)
        {
            return View(movie);
        }

        _repository.Save(movie);
        return RedirectToAction("Success");
    }
}

最后一部分是配置您的依赖注入框架,以将存储库的正确实现传递给控制器​​。现在,您可以看到获取数据的方式与控制器逻辑完全分离。这是应该的方式。始终尽量避免应用程序不同层之间的强耦合。

并回答您关于 State 属性的问题:这完全是 EF 特有的,在控制器中看到这样的东西真的很遗憾。

为了进一步提高和改进它,您将引入视图模型。视图模型是专门为满足给定视图的要求而设计的类。因此,例如 Movie 是一个域模型。领域模型不应该直接传递给视图。控制器动作不应该将域模型作为动作参数。您应该定义仅包含给定视图所需的视图模型,然后执行视图模型和域模型之间的映射。AutoMapper等框架使这变得非常简单。

于 2011-10-12T20:30:16.163 回答
2

唔。

MVC和实体框架真的没有任何关系;他们只是一起工作得很好。

if (ModelState.IsValid)验证您的视图模型。如果您不使用带有验证器的视图对象,那有点毫无意义;如果你是,那么它是非常有价值的。

if (ModelState.IsValid)括号内,您将从网页(通常是视图模型)中获取发布数据并将其应用于将其持久保存到数据库的对象。EF 经常被使用,因为一旦设置好,它就相当容易维护,而且要编写的代码也少得多。

            db.Entry(movie).State = EntityState.Modified;
            db.SaveChanges();

都是EF相关的。这些将需要由您的存储库类方法和对象替换。

            return RedirectToAction("Index");

是MVC。成功持久化到数据存储后,将控件返回到索引页面。

        return View(movie);

用于重定向回原始视图,因为验证失败。

于 2011-10-12T20:29:37.147 回答
1

您仍然会检查ModelState.IsValid,但否则您的代码将看起来像您所拥有的。

不过,这假设您的模型上有DataAnnotations属性,这是ModelState.IsValid用来检查的。这些属性可用于任何 C# 类的属性——而不仅仅是实体框架。

您最终可能会为此目的创建特定的视图模型。

于 2011-10-12T20:23:49.537 回答
0

您需要在 Movie 对象(通过 http POST 传递)和您的数据库方法 (myDBObject) 之间建立一些连接。

也许您想说myDBObject.SaveChanges(movie)并假设您的数据库代码知道如何处理对象 Movie 那么您会没事的。

于 2011-10-12T20:32:45.667 回答