asp.net-mvc 在 ASP.NET MVC 中将 Viewmodel 数据保存到数据库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16306244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 02:47:25  来源:igfitidea点击:

Saving Viewmodel data to the Database in ASP.NET MVC

asp.net-mvcasp.net-mvc-3entity-frameworkautomapper

提问by Jim

I am new to ASP.net MVC and am using a viewmodel rather than viewbags to populate my dropdowns since I've seen most people recommend against them. I have a slick UI that does cascading dropdowns and autocompletes (not shown here) but I can't seem to get my data saved back to the database.

我是 ASP.net MVC 的新手,并且使用视图模型而不是视图包来填充我的下拉列表,因为我看到大多数人都反对它们。我有一个漂亮的 UI,可以执行级联下拉菜单和自动完成(此处未显示),但我似乎无法将我的数据保存回数据库。

Models:

楷模:

   public partial class Car
    {
        public int CarID { get; set; }
        public string CarName { get; set; }
        public int ModelID { get; set; }
        public int ManufacturerID { get; set; }
        public int CarColorID { get; set; }
        public Nullable<decimal> Price { get; set; }
        public string Description { get; set; }

        public virtual CarColor CarColor { get; set; }
        public virtual Manufacturer Manufacturer { get; set; }
        public virtual CarModel CarModel { get; set; }
    }
   public partial class CarColor
    {
        public CarColor()
        {
            this.Cars = new HashSet<Car>();
        }

        public int ColorID { get; set; }
        public string ColorName { get; set; }

        public virtual ICollection<Car> Cars { get; set; }
    }
   public partial class CarModel
    {
        public CarModel()
        {
            this.Cars = new HashSet<Car>();
        }

        public int CarModelID { get; set; }
        public int ManufacturerID { get; set; }
        public string CarModelName { get; set; }

        public virtual ICollection<Car> Cars { get; set; }
        public virtual Manufacturer Manufacturer { get; set; }
    }
   public partial class Manufacturer
    {
        public Manufacturer()
        {
            this.Cars = new HashSet<Car>();
            this.Manufacturer1 = new HashSet<Manufacturer>();
            this.CarModels = new HashSet<CarModel>();
        }

        public int ManufacturerID { get; set; }
        public string ManufacturerName { get; set; }
        public Nullable<int> ParentID { get; set; }

        public virtual ICollection<Car> Cars { get; set; }
        public virtual ICollection<Manufacturer> Manufacturer1 { get; set; }
        public virtual Manufacturer Manufacturer2 { get; set; }
        public virtual ICollection<CarModel> CarModels { get; set; }
    }

ViewModel:

视图模型:

public class AnotherTestViewModel
    {
        public Car car { get; set; }

        public IEnumerable<SelectListItem> CarModels { get; set; }
        public IEnumerable<SelectListItem> Manufacturers { get; set; }
        public IEnumerable<SelectListItem> CarColors { get; set; }
    }

Controller:

控制器:

public ActionResult Create()
        {
            var model = new AnotherTestViewModel();
            using (new CarTestEntities())
            {
                model.CarModels = db.CarModels.ToList().Select(x => new SelectListItem
                {
                    Value = x.CarModelID.ToString(),
                    Text = x.CarModelName
                });
                model.Manufacturers = db.Manufacturers.ToList().Select(x => new SelectListItem
                {
                    Value = x.ManufacturerID.ToString(),
                    Text = x.ManufacturerName
                });
                model.CarColors = db.CarColors.ToList().Select(x => new SelectListItem
                {
                    Value = x.ColorID.ToString(),
                    Text = x.ColorName
                });
            }
            return View(model);
        } 

        //
        // POST: /AnotherTest/Create

        [HttpPost]
        public ActionResult Create(AnotherTestViewModel model)
        {
                if (ModelState.IsValid)
                {
                    db.Entry(model).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("Details", "AnotherTestViewModel", new { id = model.car.CarID });
                }
                return View();
        }

I saw a few recommendations to use Automapper because EntityState.Modified won't work, but I'm not sure how to configure it because using the code below didn't work.

我看到了一些使用 Automapper 的建议,因为 EntityState.Modified 不起作用,但我不确定如何配置它,因为使用下面的代码不起作用。

Mapper.CreateMap<AnotherTestViewModel, Car>();
Mapper.CreateMap<Car, AnotherTestViewModel>();
var newCar = Mapper.Map<AnotherTestViewModel, Car>(model);

Any ideas?

有任何想法吗?

回答by RiceRiceBaby

Your view model should not be interacting with the database. View Models should only be used in the presentation layer (user interface) - hence the term "View" model. You should have another model (data model) that interacts with your database. Then you should have some type of service layer that handles your conversion between your view model and your data model (and vice versa). Your data model is the model generated by Entity Framework (which I assume is what you are using). To handle updates to your database, you need to instantiate a data context, grab the data entity from your database, make changes to that entity, and call save changes all in that data context. The data context will keep track of all changes to your entities and apply the necessary changes to your database when you call "save changes". Example:

您的视图模型不应与数据库交互。视图模型应该只用于表示层(用户界面) - 因此术语“视图”模型。您应该有另一个与数据库交互的模型(数据模型)。然后你应该有某种类型的服务层来处理视图模型和数据模型之间的转换(反之亦然)。您的数据模型是由实体框架生成的模型(我假设您正在使用它)。要处理对数据库的更新,您需要实例化数据上下文,从数据库中获取数据实体,对该实体进行更改,并在该数据上下文中调用保存更改。数据上下文将跟踪对您的实体所做的所有更改,并在您调用“保存更改”时将必要的更改应用到您的数据库。例子:

public void UpdateCar(CarViewModel viewModel)
{
    using (DataContext context = new DataContext())
    {
        CarEntity dataModel = context.CarEntities.where(x => x.Id == viewModel.Id).First();

        dataModel.Name = viewModel.Name;
        dataModel.Type = viewModel.Type;

        context.SaveChanges();
    }
}

In this example, context will keep track of any changes to "dataModel". When "context.SaveChanges" is called, those changes will automatically be applied to the database.

在此示例中,上下文将跟踪对“dataModel”的任何更改。调用“context.SaveChanges”时,这些更改将自动应用于数据库。