Asp.net mvc 填充对象的简单方法
我有以下课程:Asp.net mvc 填充对象的简单方法,asp.net-mvc,architecture,entity-framework-6,Asp.net Mvc,Architecture,Entity Framework 6,我有以下课程: public class SectionViewModel { private static EFModels.VTSEntities _db = new EFModels.VTSEntities(); public int ID { get; set; } public string SectionName { get; set; } public bool Active { get; set; }
public class SectionViewModel
{
private static EFModels.VTSEntities _db = new EFModels.VTSEntities();
public int ID { get; set; }
public string SectionName { get; set; }
public bool Active { get; set; }
public string SiteName { get; set; }
}
我想从_db.Sections中选择一个元素并填充这个类的对象。我可以这样做:
public SectionViewModel(int ID)
{
var s = (from i in _db.Sections
where i.ID == ID
select new SectionViewModel()
{
ID = i.ID,
SectionName = i.SectionName,
Active = i.Active,
SiteName = i.Site.SiteName
}).FirstOrDefault();
ID = s.ID;
SectionName = s.SectionName;
Active = s.Active;
}
它可以工作,但当字段数为十时,代码是巨大的。我想写一些类似的东西
// IT DOES NOT WORK, ONLY EXAMPLE
public SectionViewModel(int ID)
{
this = (from i in _db.Sections
where i.ID == ID
select new SectionViewModel()
{
ID = i.ID,
SectionName = i.SectionName,
Active = i.Active,
SiteName = i.Site.SiteName
}).FirstOrDefault();
}
增加:
创建SectionViewModel对象(它是一个视图模型类):
但是,当然,这是不可能的,因为“this”只能用于阅读。有什么办法吗?编辑
好的,那么您将从节
构造一个节视图模型
,而不是节
。这会有一些不同,但我的原始答案中仍有许多评论适用
更好的方法是
public ActionResult SectionForm(int id)
{
Section section = this._context.Sections.Find(id);
SectionViewModel model = .... // Mapping code
return View(model);
}
此部分//映射代码
可以是将属性从部分
复制到模型
的任何内容。你可以用AutoMapper
在SectionViewModel
的构造函数中不这样做的原因是首先不应该存在静态上下文。您可以创建和处理上下文来代替。但是谁说SectionViewModel
s总是单独构建的呢?也许在另一种方法中,您将返回它们的列表。单独创建每个模型将非常低效。这种方法在那里是合适的
原文 在构造函数中构造一个对象(这是由部分
var s=(…).FirstOrDefault()
)发生的事情)然后将其属性复制到构造函数的所有者(类型相同,节
)。更荒谬的是,在查询中,您还从一个节构造了一个节。所以在运行声明之后
Section model = new Section(id);
…您已经构建了三个相同的部分,最后一个部分被最终使用:
第1节:来自i in\u db.Sections,其中i.ID==ID选择i
第2节:选择新节(){…}
第3节:节(内部ID)
EF甚至不允许这样的声明
from i in _db.Sections
select new Section() {...}
它将告诉您不能在LINQtoEntities查询中构造实体
但是删除这个selectnewsection(){…}
甚至不是声音重构的开始。整个结构是荒谬的
另一个糟糕的做法是使用静态上下文。上下文的设计寿命很短,因为它们缓存从数据库中获取的每个实体。静态上下文是内存泄漏
实现你想要的方法很简单
public ActionResult SectionForm(int id)
{
Section model = this._context.Sections.Find(id);
return View(model);
}
…其中,this.\u context
是您的vtSenties
的一个实例,该实例是根据控制器实例创建的(或通过控制容器的反转注入)
您的编程风格让人隐约联想到一种与EF的存储库/工作单元模式(其中,DbSet
是一种repo,DbContext
是一种UoW)不能很好地混合的模式。它还打破了EF赖以建立的持续无知原则。它破坏了查询的可组合性,并且很容易导致n+1
查询。@Gert Arnold,我补充道,如果我正确理解您的问题,这就是为什么会存在类似产品。我建议您阅读如何使用MVC+EF。您的代码是错误模式的密集集合,显然是受到过去编程传统的微弱回响的启发。回到绘图板上,我读了很多这样的文章。你能描述一下为什么我的方法是错误的吗?如果有必要,我只想在构造函数中填充我的视图模型。哪种模式被破坏了?我的分区类是视图模型类,而不是EF类!所以,你的例子不合适。为了更清楚,我将在问题中删除Section类到SectionViewModel!使用EF模型类进行查看是非常糟糕的方法(我可以在您的控制器方法中看到)。EF模型是EF模型,视图模型是视图模型!请参阅修改后的答案。如果我想从2个或更多实体(即SectionViewModel由节填充,一个参数由站点填充),您的方法不合适。请指出一种情况,为什么您的方法不好。您建议获取模型类的对象,然后复制到视图模型类的对象。
public ActionResult SectionForm(int id)
{
Section model = this._context.Sections.Find(id);
return View(model);
}