容易的方法来填充对象 [英] Easy way to fill object

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

问题描述

我有以下类:

  public class SectionViewModel 
{
private static EFModels.VTSEntities _db = new EFModels.VTSEntities();
public int ID {get;组; }
public string SectionName {get;组; }
public bool Active {get;组; }
public string SiteName {get;组;
}

我想从_db.Sections中选择一个元素,并填充此对象类。我可以这样做:

  public SectionViewModel(int ID)
{
var s =从我在_db.Sections
其中i.ID == ID
选择新的SectionViewModel()
{
ID = i.ID,
SectionName = i.SectionName ,
Active = i.Active,
SiteName = i.Site.SiteName
})。FirstOrDefault();
ID = s.ID;
SectionName = s.SectionName;
Active = s.Active;
}

它可以工作,但是当字段数为十时,代码是巨大的。我想写一些类似的东西。

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
{
this =(从我在_db.Sections
其中i.ID == ID
选择新的SectionViewModel()
{
ID = i .ID,
SectionName = i.SectionName,
Active = i.Active,
SiteName = i.Site.SiteName
})。FirstOrDefault();
}

ADDED:



创建SectionViewModel对象(它是一个View模型类):

  public ActionResult SectionForm(int?id)
{
SectionViewModel model = new SectionViewModel(id);
return View(model);
}

但当然这是不可能的,因为这个只能用于阅读。任何方式来做?

解决方案

修改



OK,所以你从中构造一个 SectionViewModel 而不是一个 Section 。这样做有所不同,但是我的原始答案中还有很多言论适用。



一个更好的方法是

  public ActionResult SectionForm(int id)
{
Section section = this._context.Sections.Find(id);
SectionViewModel model = .... //映射代码
return View(model);
}

这部分 //映射代码可以将属性从部分复制到模型中。您可以使用AutoMapper。



SectionViewModel 的构造函数中不这样做的原因是不应该首先是一个静态的上下文。您可以创建和处理上下文。但是谁说, SectionViewModel 总是单独构建?也许在另一种方法你会返回一个列表。单独创建每个模型将是非常低效的。 AutoMapper的 Project()。到 方法将适用于此。 / p>




原始文本



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

  Section model = new Section(id); 

...您已经构建了三个相同的 Section 其中最后一个最终被使用:



第1节:$ code从我在_db.Sections其中i.ID == ID选择我。

第2节:选择新的Section(){...}

第3节: Section(int ID)



而EF甚至不允许像

 从我在_db.Sections 
中选择新的Section(){...}
/ pre>

它会告诉你,你不能在LINQ到实体查询中构造一个实体。



但是删除这个选择新的Section(){...} 甚至不是声音重构的开始。整个构造是荒谬的。



另一个不好的做法是有静态上下文。上下文设计为具有较短的使用寿命,因为它们缓存从数据库中获取的每个实体。一个静态上下文是一个内存泄漏。



实现你想要的方式是简单的...

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

...其中 this._context 是您的 VTSEntities 的一个实例,它是根据控制器实例创建的(或通过控制容器的反转注入)。



您的编程风格让人联想到 活动记录 / a>,与EF的存储库/工作单元格不兼容的模式(其中 DbSet 是一个repo和一个 DbContext 是一个UoW)。它还打破了EF建立的持久性无知原则。它打破了查询的可组合性,很容易导致 n + 1 查询。


I have the following class:

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

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

ADDED:

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?

解决方案

Edit

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

This part // Mapping code can be anything that copies properties from section to model. You could use 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 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.


Original text

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 Sections of which the last one is finally used:

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

And EF doesn't even allow a statement like

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

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

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

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天全站免登陆