填充对象的简单方法 [英] Easy way to fill object

查看:27
本文介绍了填充对象的简单方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程:

    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;
    }

它可以工作,但是当字段数为十时,代码很庞大.我想写类似的东西

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);
    }

但是,当然,这是不可能的,因为this"仅供阅读.有什么办法吗?

but, of course, it's impossible because "this" is available only for read. Any way to do it?

推荐答案

编辑

好的,所以你从 Section 构建了一个 SectionViewModel,而不是一个 Section.这会有所不同,但我的原始答案中的许多评论仍然适用.

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.

更好的方法是

public ActionResult SectionForm(int id)
{
    Section section = this._context.Sections.Find(id);
    SectionViewModel model = .... // Mapping code
    return View(model);
}

这部分//映射代码可以是任何将属性从section复制到model的东西.您可以使用 AutoMapper.

This part // Mapping code can be anything that copies properties from section to model. You could use AutoMapper.

SectionViewModel 的构造函数中不这样做的原因是首先不应该有静态上下文.您可以改为创建和处理上下文.但是谁说 SectionViewModel 总是单独构造的?也许在另一种方法中,您将返回它们的列表.单独创建每个模型会非常低效.AutoMapper 的 Project().To 方法在那里很合适.

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 SectionViewModels 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.

原文

在构造函数中构造一个对象(这就是 var s = (...).FirstOrDefault() 部分发生的事情)然后将其属性复制到该对象的所有者是荒谬的构造函数,同类型,Section.更荒谬的是,在查询中您从一个部分构造一个Section.所以在运行语句之后...

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);

...你已经构建了三个相同的Section,最后一个使用了:

...you have constructed three identical Sections of which the last one is finally used:

Section 1: from i in _db.Sections where i.ID == ID select i.
第 2 节:select new Section() {...}
第 3 节:Section(int ID)

Section 1: from i in _db.Sections where i.ID == ID select i.
Section 2: select new Section() {...}
Section 3: Section(int ID)

而且 EF 甚至不允许像

And EF doesn't even allow a statement like

from i in _db.Sections
select new Section() {...}

它会告诉您不能在 LINQ-to-Entities 查询中构造实体.

It will tell you that you can't construct an entity in an LINQ-to-Entities query.

但是删除这个 select new Section() {...} 甚至不是声音重构的开始.整个结构是荒谬的.

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,与 EF 的存储库/工作单元模式(其中 DbSet 是一个存储库,而 DbContext 是一个 UoW)不能很好地混合的模式.它还打破了构建 EF 的persistence ignorance 原则.它破坏了查询的可组合性,很容易导致 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆