2

我在执行以下映射时遇到问题:

域(简化版):

public class Ad
{
    // Primary properties
    public int Kms { get; set; }

    // Navigation properties
    public virtual Model Model { get; set; }
}

DTO:

public class CreateAdDto
{
    // Primary properties
    public int Kms { get; set; }

    // Navigation properties
    public virtual ModelDto Model { get; set; }
}

视图模型:

public class CreateAdViewModel
{
    // Primary properties
    public int Kms { get; set; }

    public int Make_Id { get; set; }
    public int Model_Id { get; set; }

    // Navigation properties
    public IEnumerable<SelectListItem> MakeList { get; set; }
    public IEnumerable<SelectListItem> ModelList { get; set; }
}

在控制器中,当我进行映射时,我会从视图的下拉列表中丢失 Make_ID:

    public virtual ActionResult Create(CreateAdViewModel adViewModel)
    {
        if (ModelState.IsValid)
        {
            var adDto = Mapper.Map<CreateAdViewModel, CreateAdDto>(adViewModel);

            _adService.CreateAd(adDto);
        }

        return RedirectToAction(MVC.Home.Index());
    }

映射是:

        Mapper.CreateMap<CreateAdViewModel, CreateAdDto>()

谢谢。

4

5 回答 5

1

正如您所提到的,广告需要知道 Model_Id 并将其设置到模型中

Mapper.CreateMap<CreateAdDto, Ad>()
         .ForMember(dest => dest.Model, opt => opt.MapFrom(src => new Model { Id = src.Model_Id }));

您还需要从另一个映射端让 D 知道从哪里获取模型 ID。

Mapper.CreateMap<Ad, CreateAdDto>()
         .ForMember(dest => dest.Model_Id, opt => opt.MapFrom(src => src.Model.Id}));

上面的代码不安全,因为应该添加验证以查看 Model 是否为 null。

对于您的其余代码,您似乎做对了。实体框架部分需要您附加,因为实体模型已经存在,否则,EF 会将此实体插入数据库。

于 2012-10-25T12:58:19.170 回答
0

CreateAdDto 没有 Make 导航属性或 Make_Id 属性。

于 2012-10-24T16:08:04.420 回答
0

根据我在您的问题中看到的内容,我建议采用一种简单的方法。您的应用程序是中等规模的。我的经验说,你应该非常小心地考虑可维护性。所以尝试为自己创建一个简单的应变前向方法,如下面的方法: 应用架构

我可以详细描述所有层,但要注意您的问题的标题,我更喜欢仅描述模型(业务对象)层:

模型或业务对象层

好的!如您所见,PM.Model 包括:两个子文件夹包含我们的 ViewModel,在库的根目录中,我们有一个 .tt 文件,其中包含实体框架对象(PO​​CO 类),我们有一个 Mapper 文件夹(因为我不喜欢使用 autoMapper 或第三个像这样的聚会:))。

您可以在 Domain 层看到 IListBox 接口。我把所有的 ListBox 容器放到这个接口上。

我希望当前的方法对您有用,但最后我建议删除其中一层 DTO 或 ViewModel,因为将来会非常复杂。

祝你好运

于 2012-11-13T22:18:31.913 回答
0

经过一番研究找到的解决方案:

视域:

public class CreateAdViewModel
{
    // Primary properties
    public int Kms { get; set; }

    public int Make_Id { get; set; }
    public int Model_Id { get; set; }

    // Navigation properties
    public IEnumerable<SelectListItem> MakeList { get; set; }
    public IEnumerable<SelectListItem> ModelList { get; set; }
}

DTO:

public class CreateAdDto
{
    // Primary properties
    public int Kms { get; set; }
    public int Model_Id { get; set; }

    // Navigation properties
    //public virtual ModelDto Model { get; set; }
}

领域:

public class Ad
{
    // Primary properties
    public int Kms { get; set; }

    // Navigation properties
    public virtual Model Model { get; set; }
}

视图模型-> Dto 映射:

        Mapper.CreateMap<CreateAdViewModel, CreateAdDto>();

Dto -> 域映射:

        Mapper.CreateMap<CreateAdDto, Ad>()
             .ForMember(dest => dest.Model, opt => opt.MapFrom(src => new Model { Id = src.Model_Id })); 

注意:

为了使用实体框架实现这一点,我必须首先将模型实体附加到上下文,然后添加新广告:

    public void CreateAd(CreateAdDto adDto)
    {
        var adDomain = Mapper.Map<CreateAdDto, Ad>(adDto);

        _modelRepository.Attach(adDomain.Model);

        _adRepository.Add(adDomain);
        _adRepository.Save();
    }

希望这是最佳实践。

顺便说一句,我想对这种方法发表一些意见。

谢谢。

于 2012-10-25T10:53:23.817 回答
-2

你知道这些映射的成本吗?!对于简单的插入,您有 2 层映射(在到达实体框架之前)。我们可以在不到 2 层的映射中执行更复杂的 CRUD。如何考虑这段代码的可维护性?

请牢记 DRY、KISS、SOLID 约定,并将其放在日常工作的首位。

祝你好运

于 2012-11-12T04:39:55.733 回答