我有以下课程:
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对象(它是一个View模型类):
public ActionResult SectionForm(int? id)
{
SectionViewModel model = new SectionViewModel(id);
return View(model);
}
但是,当然,这是不可能的,因为“this”仅适用于阅读。有办法吗?
答案 0 :(得分:2)
修改强>
好的,您可以从SectionViewModel
构建Section
,而不是Section
。这有所不同,但我的原始答案仍有许多评论适用。
更好的方法是
public ActionResult SectionForm(int id)
{
Section section = this._context.Sections.Find(id);
SectionViewModel model = .... // Mapping code
return View(model);
}
此部分// Mapping code
可以是将属性从section
复制到model
的任何内容。您可以使用AutoMapper。
不在SectionViewModel
的构造函数中执行此操作的原因是,首先不应存在静态上下文。您可以创建和处理上下文。但谁说SectionViewModel
总是单独构建?也许在另一种方法中,您将返回它们的列表。单独创建每个模型的效率非常低。 AutoMapper's Project().To
方法适用于那里。
原始文字
在构造函数中构造一个对象(这是部件var s = (...).FirstOrDefault()
发生的事情),然后将其属性复制到构造函数的所有者,这是相同的类型Section
,这是荒谬的。在查询中你还从一个部分构造一个Section
更荒谬。所以在运行声明后......
Section model = new Section(id);
...你构建了三个相同的Section
,其中最后一个最终被使用:
第1节:from i in _db.Sections where i.ID == ID select i
。
第2节:select new Section() {...}
第3节:Section(int ID)
EF甚至不允许像
那样的声明from i in _db.Sections
select new Section() {...}
它会告诉您无法在LINQ-to-Entities查询中构造实体。
但删除此select new Section() {...}
甚至不是声音重构的开始。整个构造是荒谬的。
另一个不好的做法是拥有静态上下文。上下文的设计寿命较短,因为它们会缓存从数据库中获取的每个实体。静态上下文是内存泄漏。
实现目标的方法就是......
public ActionResult SectionForm(int id)
{
Section model = this._context.Sections.Find(id);
return View(model);
}
...其中this._context
是每个控制器实例创建的VTSEntities
实例(或由Inversion of Control容器注入){。p>
您的编程风格隐约让人联想到Active Record,这种模式与EF的存储库/工作单元模式不完美混合(其中DbSet
是回购,而DbContext
是一个UoW)。它还打破了构建EF的 persistance ignorance 原则。它破坏了查询可组合性,并且很容易导致n + 1
查询。