当使用带有 EF 4.1 Code First 的 ASP.NET MVC 3 时,我只能编辑主表,我做错了啥?

Posted

技术标签:

【中文标题】当使用带有 EF 4.1 Code First 的 ASP.NET MVC 3 时,我只能编辑主表,我做错了啥?【英文标题】:When using ASP.NET MVC 3 with EF 4.1 Code First, I can only edit the main table, what am I doing wrong?当使用带有 EF 4.1 Code First 的 ASP.NET MVC 3 时,我只能编辑主表,我做错了什么? 【发布时间】:2011-07-06 14:49:37 【问题描述】:

简要说明我在做什么。我正在使用 ASP MVC 3 和 EF Code First 方法创建一个相当粗糙的 IS 资产跟踪数据库。我可以创建一个新资产。我可以查看资产的详细信息。我什至可以显示编辑视图并编辑 AssetTag。但是,该记录不会更新任何其他字段。例如,如果我编辑 LocationName 。它会表现得好像它正在发布并将我返回到索引视图,但该记录实际上从未发布过更改。

我在下面创建了模型

public class AssetModel

    public int id  get; set; 
    public string AssetTag  get; set; 
    public virtual Location Location  get; set; 
    public virtual Hardware Hardware  get; set; 
    public virtual Software Software  get; set; 
    public virtual User User  get; set; 




public class Location

    public int LocationId  get; set; 
    public string LocationName  get; set; 

public class Hardware

    public int HardwareId  get; set; 
    public string Manufacturer  get; set; 
    public string Make  get; set; 
    public string Model  get; set; 



public class Software

    public int SoftwareId  get; set; 
    public string PublisherName  get; set; 
    public string SoftwarePackageName  get; set; 
    public string SoftwarePackageVersion  get; set; 
    public string SerialNumber  get; set; 
    public bool IsVolumeLicense  get; set;  // as in "Yes this is a Vol. Lic. Agreement"
    public LicenseAgreement LicenseAgreement  get; set; 


public class LicenseAgreement 

    public int LicId  get; set; 
    public string VolumeLicenseAgreementCompany  get; set; 
    public string AgreementIdentifier  get; set;  
    public DateTime VolumeLicenseStartDate  get; set; 
    public DateTime VolumeLicenseExpirationDate  get; set; 
    public Int16 NumberOfLicenses  get; set; 



public class User

    // may remove this at some time and pull from Active Directory.
    // for now we take the easy route.
    public int UserId  get; set; 
    public string FirstName  get; set; 
    public string LastName  get; set; 

我有这个使用上述 AssetModel 的 DbDataSet:

public class AssetContext : DbContext

    public DbSet<AssetModel> Assets  get; set; 
 

在我的 AssetController 中,我有这个用于编辑:

public ActionResult Edit(int id)
    
        AssetModel assetmodel = db.Assets.Find(id);
        return View(assetmodel);
    
    //
    // POST: /Asset/Edit/5

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

这里是 Edit.cshtml

@model ISHelpDesk.Models.AssetModel

@
     ViewBag.Title = "Edit";
  

 <h2>Edit</h2>
@using (Html.BeginForm("Edit", "Asset")) 
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>AssetModel</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.AssetTag)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.AssetTag)
        @Html.ValidationMessageFor(model => model.AssetTag)
    </div>
    <div class="editor-label">
        @Html.LabelFor(model => model.Location.LocationName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Location.LocationName)
        @Html.ValidationMessageFor(model => model.Location.LocationName)
    </div>

    </fieldset>
<p><input type="submit" value="Save"</p>
 

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

【问题讨论】:

我也忘了提到我也在使用 SQL Server CE。 【参考方案1】:

你的AssetContext应该是

public class AssetContext : DbContext

    public DbSet<AssetModel> Assets  get; set; 
    public DbSet<Location> Locations  get; set; 
    public DbSet<Hardware> Hardwares  get; set; 
    public DbSet<Software> Softwares  get; set; 
    public DbSet<LicenseAgreement> LicenseAgreements  get; set; 
    public DbSet<User> Users  get; set; 

这是将您的每个课程注册为DbContext 中的一个表,您之前所显示的DbContext 仅包含AssetModel

更新:问题可能是当您进入编辑的 post 方法时,资产不再与最初加载它的数据库资产相关联,请尝试更改它到

public ActionResult Edit(int id)

    AssetModel assetmodel = db.Assets.Find(id);
    return View(assetmodel);


[HttpPost]
public ActionResult Edit(int id, FormCollection collection)

    AssetModel assetmodel = db.Assets.Find(id);

    if (TryUpdateModel(assetmodel))
    
        db.SaveChanges();
        return RedirectToAction("Index");
    
    return View(assetmodel);

显然这可能不是你想要的行为我只是想看看你是否可以让一些更改保持不变并从那里开始

【讨论】:

感谢您的帮助。我明白你在说什么,我做出了改变,但仍然没有更新。可以想象,这很令人沮丧。 现在仍然存在。谢谢你。现在我必须想清楚为什么。你是小屁孩!【参考方案2】:

您的模型类应该扩展 DbContext:

 public class AssetModel :DbContext

【讨论】:

很好的尝试,但不幸的是没有奏效。我真的在祈祷,希望这是一件愚蠢的事情。 :) 谢谢,我应该已经发布了整个 dbcontext,它已经在那里了。 我真的开始认为 EF Code First 存在问题 我注意到有些属性是虚拟的。这将迫使 EF 延迟加载它们。您是否尝试过删除 virtual 关键字? 再次感谢,但事实并非如此。不过,我感谢您的帮助。

以上是关于当使用带有 EF 4.1 Code First 的 ASP.NET MVC 3 时,我只能编辑主表,我做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章

EF 4.1:使用 Fluent 映射从 Code First 中查找关键属性类型

EF 4.1 Code First 不会为 List<string> 创建列

EF 4.1 中使用 Code First 的 ComplexType 集合属性

在使用 EF 4.1 Code-First 的 Include 和/或 Select 方法时订购导航属性?

EF 4.1 Code First - 我应该使用啥模式?

使用EF 4.1 Fluent Code First的每类型表继承