繁体   English   中英

MVC 4-实体框架,ViewModel和对象上下文

[英]MVC 4 - Entity Framework, ViewModel and Object Context

我将Entity Framework与MVC 4一起使用来开发Web应用程序。 我还使用了一个名为VehicleTypeViewModel的ViewModel,它是这样创建的:

public class VehicleTypeViewModel
{
    public VehicleType VehicleType { get; set; }

    public ProductType ProductType { get; set; }

    [RegularExpression(@"^[a-zA-Zàéèêçñ\s][a-zA-Zàéèêçñ\s-]+$", ErrorMessage = "Invalid name !")]
    public string Name { get; set; }

    [Range(0, 300)]
    public int CO2 { get; set; }

    public List<SelectListItem> ProductCompanies { get; set; }

    public List<SelectListItem> MotorTypes { get; set; }
}

在我的“编辑操作”中,一切都很好,但有一件事情:当我调试并到达db.Attach(...)步骤时,我的应用程序会抛出一个异常,内容为:

The object cannot be attached because it is already in the object context. An object can only be reattached when it is in an unchanged state.

这是我的张贴动作:

[HttpPost]
public ActionResult Edit(VehicleTypeViewModel vtvm)
{
    ViewBag.Id_VehicleMotorType = new SelectList(db.VehicleMotorTypes, "Id_VehicleMotorType", "Name", vtvm.VehicleType.Id_VehicleMotorType);
    ViewBag.Id_ProductCompany = new SelectList(db.ProductCompanies, "Id_ProductCompany", "Name", vtvm.ProductType.Id_ProductCompany);

    vtvm.ProductCompanies = db.ProductCompanies.ToList().Select(c => new SelectListItem { Text = c.Name, Value = c.Id_ProductCompany.ToString() }).ToList();
    vtvm.MotorTypes = db.VehicleMotorTypes.ToList().Select(v => new SelectListItem { Text = v.Name, Value = v.Id_VehicleMotorType.ToString() }).ToList();

    VehicleType vehicleType = db.VehicleTypes.Single(v => v.Id_VehicleType == vtvm.VehicleType.Id_VehicleType);
    ProductType productType = db.ProductTypes.Single(p => p.Id_ProductType == vtvm.ProductType.Id_ProductType);
    VehicleMotorType vehicleMotorType = null;

    ModelStateDictionary errors = Validator.isValid(vtvm.ProductType);

    if (ModelState.IsValid)
    {
        if (errors.Count > 0)
        {
            ModelState.Merge(errors);
            return View(vtvm);
        }

        productType.Model = vtvm.ProductType.Model;
        productType.CatalogPrice = vtvm.ProductType.CatalogPrice;
        productType.Id_ProductCompany = vtvm.ProductType.Id_ProductCompany;

        if (!string.IsNullOrWhiteSpace(vtvm.Name) && (vtvm.CO2 > 0))
        {
            vehicleMotorType = new VehicleMotorType()
            {
                CO2 = vtvm.CO2,
                Name = vtvm.Name
            };

            vehicleType.CO2 = vtvm.VehicleType.CO2;
            vehicleType.VehicleMotorType = vehicleMotorType;
            vehicleType.Id_ProductType = vtvm.ProductType.Id_ProductType;
        }
        else
        {
            vehicleType.CO2 = vtvm.VehicleType.CO2;
            vehicleType.Id_ProductType = vtvm.ProductType.Id_ProductType;
            vehicleType.Id_VehicleMotorType = vtvm.VehicleType.Id_VehicleMotorType;
        }

        db.VehicleTypes.Attach(vehicleType);
        db.ProductTypes.Attach(productType);

        db.ObjectStateManager.ChangeObjectState(vehicleType, EntityState.Modified);
        db.ObjectStateManager.ChangeObjectState(productType, EntityState.Modified);

        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(vtvm);
}

我不知道为什么要处理这种错误。 有什么办法解决这个问题吗?

Traffy,

简短的答案,您应该删除这2行

 db.VehicleTypes.Attach(vehicleType);
 db.ProductTypes.Attach(productType);

当您从EntityFramework实例检索任何实体并修改任何属性时,实体框架将自动跟踪更改。

要将更改应用到数据库,您只需要调用

db.SaveChanges();

为了更好地理解何时使用Add和Attach方法,您应该阅读Entity Framework 4-AddObject vs Attach

希望对您有所帮助。

只需删除“附加”,因为对象已经在数据库中,无需再次附加,只需更改状态并保存更改

 var comp = (from com in db.tbl_CompGroup where com.Group_Id == GroupID select com).FirstOrDefault();

        comp.Survey_Est = surveyPost.Survey_Est;

        //db.tbl_CompGroup.Attach(comp);
        db.ObjectStateManager.ChangeObjectState(comp, System.Data.EntityState.Modified);
        db.SaveChanges();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM