在 MVC 模型中编辑对象关系
Editing object relations in MVC models
我在 MVC 5.2.3 中遇到一个相关对象的问题,Entity Framework 6. 我无法更新与模型中另一个对象的关系。有一个具有 属性 InstrumentModel 和继承自 BaseModel 的 int ID 的 AudiogramModel。
public class AudiogramModel : BaseModel
{
//Other properties...
public InstrumentModel Instrument { get; set; }
}
仪器型号定义如下:
public class InstrumentModel : BaseModel
{
public string Name { get; set; }
}
就像听力图从 BaseModel 继承一个密钥 - ID 一样。
在控制器 AudiogramController 中,方法 Edit 应该在视图模型 AudiogramCreateEditViewModel 中接收带有 InstrumentModel 的整个 AudiogramModel,然后将编辑后的 AudiogramModel 与 InstrumentModel 保存在里面。
视图模型定义为:
public class AudiogramCreateEditViewModel
{
public AudiogramModel Audiogram { get; set; }
public int[] Frequencies { get; set; }
public List<InstrumentModel> Instruments { get; set; }
}
虽然频率和列表并不重要(因为它们用于将这些模型传递到编辑视图),但其中有听力图 属性,这让我很感兴趣。
public ActionResult Edit(AudiogramCreateEditViewModel audiogramEdit)
{
if (ModelState.IsValid)
{
if (audiogramEdit.Audiogram.IsMusician == true)
{
//db is the standard context of the controller
InstrumentModel instrument = db.InstrumentModels.FirstOrDefault<InstrumentModel>(x => x.Name == audiogramEdit.Audiogram.Instrument.Name);
if (instrument == null)
{
db.InstrumentModels.Add(audiogramEdit.Audiogram.Instrument);
db.SaveChanges();
}
else
{
audiogramEdit.Audiogram.Instrument = instrument;
}
}
else
{
audiogramEdit.Audiogram.Instrument = null;
}
db.AudiogramModels.Attach(audiogramEdit.Audiogram);
db.Entry(audiogramEdit.Audiogram).State = EntityState.Modified;
var a = db.ChangeTracker.Entries();
db.SaveChanges();
return RedirectToAction("Index");
}
}
模型通过了验证,看起来没问题。问题是,尽管听力图模型是正确的并且可以用 db.AudiogramModels.Add(audiogramEdit.Audiogram) 保存;没有办法更新它。更重要的是,没有行 db.AudiogramModels.Attach(audiogramEdit.Audiogram);实体追踪器甚至不追踪 audiogramEdit.Audiogram。有没有办法解决这个问题?
这是你无法做到的 "fix"。请记住代码真正在做什么。在您的 Get 操作中,您正在查找一个 AudiogramCreateEditViewModel
,对其进行序列化(及其所有属性),并将其发送给客户端以在其网页上呈现。客户端重新序列化它并将其发送回您的 Edit 方法。服务器反序列化它并给你 new 一个 AudiogramCreateEditViewModel
实例。
EntityFramework 无法了解 MVC 为您创建的这个新实例。如果你想做一个更新,你必须告诉它的上下文。最简单的方法是再次从上下文中获取对象并从 ViewModel 中复制属性。
您可能还会注意到,如果您手动复制属性,则根本不需要在 ViewModel 上拥有 AudiogramModel 实例。您可以创建一个更简单的 class,它只包含您希望编辑视图的属性和一个可用于查找域模型的 Id。在长 运行 中,这大大简化了您的 UI 层。
我在 MVC 5.2.3 中遇到一个相关对象的问题,Entity Framework 6. 我无法更新与模型中另一个对象的关系。有一个具有 属性 InstrumentModel 和继承自 BaseModel 的 int ID 的 AudiogramModel。
public class AudiogramModel : BaseModel
{
//Other properties...
public InstrumentModel Instrument { get; set; }
}
仪器型号定义如下:
public class InstrumentModel : BaseModel
{
public string Name { get; set; }
}
就像听力图从 BaseModel 继承一个密钥 - ID 一样。
在控制器 AudiogramController 中,方法 Edit 应该在视图模型 AudiogramCreateEditViewModel 中接收带有 InstrumentModel 的整个 AudiogramModel,然后将编辑后的 AudiogramModel 与 InstrumentModel 保存在里面。
视图模型定义为:
public class AudiogramCreateEditViewModel
{
public AudiogramModel Audiogram { get; set; }
public int[] Frequencies { get; set; }
public List<InstrumentModel> Instruments { get; set; }
}
虽然频率和列表并不重要(因为它们用于将这些模型传递到编辑视图),但其中有听力图 属性,这让我很感兴趣。
public ActionResult Edit(AudiogramCreateEditViewModel audiogramEdit)
{
if (ModelState.IsValid)
{
if (audiogramEdit.Audiogram.IsMusician == true)
{
//db is the standard context of the controller
InstrumentModel instrument = db.InstrumentModels.FirstOrDefault<InstrumentModel>(x => x.Name == audiogramEdit.Audiogram.Instrument.Name);
if (instrument == null)
{
db.InstrumentModels.Add(audiogramEdit.Audiogram.Instrument);
db.SaveChanges();
}
else
{
audiogramEdit.Audiogram.Instrument = instrument;
}
}
else
{
audiogramEdit.Audiogram.Instrument = null;
}
db.AudiogramModels.Attach(audiogramEdit.Audiogram);
db.Entry(audiogramEdit.Audiogram).State = EntityState.Modified;
var a = db.ChangeTracker.Entries();
db.SaveChanges();
return RedirectToAction("Index");
}
}
模型通过了验证,看起来没问题。问题是,尽管听力图模型是正确的并且可以用 db.AudiogramModels.Add(audiogramEdit.Audiogram) 保存;没有办法更新它。更重要的是,没有行 db.AudiogramModels.Attach(audiogramEdit.Audiogram);实体追踪器甚至不追踪 audiogramEdit.Audiogram。有没有办法解决这个问题?
这是你无法做到的 "fix"。请记住代码真正在做什么。在您的 Get 操作中,您正在查找一个 AudiogramCreateEditViewModel
,对其进行序列化(及其所有属性),并将其发送给客户端以在其网页上呈现。客户端重新序列化它并将其发送回您的 Edit 方法。服务器反序列化它并给你 new 一个 AudiogramCreateEditViewModel
实例。
EntityFramework 无法了解 MVC 为您创建的这个新实例。如果你想做一个更新,你必须告诉它的上下文。最简单的方法是再次从上下文中获取对象并从 ViewModel 中复制属性。
您可能还会注意到,如果您手动复制属性,则根本不需要在 ViewModel 上拥有 AudiogramModel 实例。您可以创建一个更简单的 class,它只包含您希望编辑视图的属性和一个可用于查找域模型的 Id。在长 运行 中,这大大简化了您的 UI 层。