简单的方法来填充对象 [英] Easy way to fill object
问题描述
我有以下类:
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选择一个元素,填补了这一类的对象。我可以做它喜欢它:
I want to select one element from _db.Sections and fill object of this class. I can do it like it:
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;
}
它的工作原理,但是当田数为几十,code是巨大的。我想编写类似的东西。
It works, but when count of fields is tens, code is huge. I would like to write something similar
// 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对象(这是一个视图模型类):
Create SectionViewModel object (it's a View model class):
public ActionResult SectionForm(int? id)
{
SectionViewModel model = new SectionViewModel(id);
return View(model);
}
不过,当然,这是不可能的,因为这仅适用于读取可用。任何办法做到这一点?
but, of course, it's impossible because "this" is available only for read. Any way to do it?
推荐答案
修改
OK,让你构建一个 SectionViewModel
,而不是部分
,从科
。这使得一些区别,但是从我原来的答复还是很多的情况也适用。
OK, so you construct a SectionViewModel
, not a Section
, from a Section
. That makes some difference, but still many remarks from my original answer apply.
有一个更好的办法来做到这一点。
A better way to do this is
public ActionResult SectionForm(int id)
{
Section section = this._context.Sections.Find(id);
SectionViewModel model = .... // Mapping code
return View(model);
}
这部分 //映射code
可以是任何东西,从部分
到<$ C复制性$ C>模式。你可以使用AutoMapper。
This part // Mapping code
can be anything that copies properties from section
to model
. You could use AutoMapper.
之所以不以 SectionViewModel
做到这一点的构造是不应该有一个静态的背景下出现在首位。你可以创建和处理代替上下文。但谁说, SectionViewModel
,则总是单独构建的?也许在另一种方法中,将返回它们的列表。分别创建每个模型将是非常低效的。 AutoMapper的项目()。为了
做法是适当的在那里。
The reason not to do this in SectionViewModel
's constructor is that there shouldn't be a static context there in the first place. You could create and dispose a context in stead. But who says that SectionViewModel
s are always constructed individually? Maybe in another method you will return a list of them. Creating each model separately would be highly inefficient. AutoMapper's Project().To
approach would be appropriate there.
原文
这是荒谬的,构建在构造函数中的对象(这是由部分变种S =(...)会发生什么。FirstOrDefault()
),然后复制其属性构造函数的所有者,这是同类型,部分
。在查询您的也的从部分构造部分
这更荒谬。因此运行会后声明...
It's absurd to construct an object in a constructor (which is what happens by the part var s = (...).FirstOrDefault()
) and then copy its properties to the owner of the constructor, which is the same type, Section
. It's even more absurd that in the query you also construct a Section
from a section. So after running the statement...
Section model = new Section(id);
...你已经构建三个相同的部分
■哪些的最后一个最终使用:
...you have constructed three identical Section
s of which the last one is finally used:
第1节:从我在那里_db.Sections == i.ID选择ID我
结果
第2节:选择新科(){...}
结果
第3节:科(INT ID)
和EF甚至不允许像
from i in _db.Sections
select new Section() {...}
它会告诉你,你不能在LINQ到实体查询构建的一个实体。
It will tell you that you can't construct an entity in an LINQ-to-Entities query.
但除去该选择新科(){...}
是一个健全的重构甚至没有开始。整个结构是荒谬的。
But removing this select new Section() {...}
is not even the beginning of a sound refactoring. The whole construct is absurd.
另外一个不好的做法是有一个静态的环境。上下文被设计成具有寿命很短,因为它们缓存每个实体,他们从数据库中获取。静态上下文是内存泄漏。
Another bad practice is to have a static context. Contexts are designed to have a short lifespan, because they cache each entity they fetch from the database. A static context is a memory leak.
要实现你想要的方式简直是...
The way to achieve what you want is simply...
public ActionResult SectionForm(int id)
{
Section model = this._context.Sections.Find(id);
return View(model);
}
...其中 this._context
是一个实例你的 VTSEntities
即每个控制器实例创建(或通过控制容器的一个反转)注入。
...where this._context
is an instance of your VTSEntities
that is created per controller instance (or injected into it by an Inversion of Control container).
您的编程风格是依稀让人想起的的Active Record 的,一不与工作模式(其中 DbSet
是一个回购和的DbContext
的EF的存储库/单位拌匀模式是一个UOW)。这也打破了的持久性的无知的原则,即EF是建立在。它打破了查询,组合性,它容易引起 N + 1
查询。
Your programming style is faintly reminiscent of Active Record, a pattern that doesn't mix well with EF's repository/unit of work pattern (where DbSet
is a repo and a DbContext
is a UoW). It also breaks the persistance ignorance principle that EF is built on. It breaks query composability and it easily causes n + 1
queries.
这篇关于简单的方法来填充对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!