潜在的AutoMapper问题

时间:2014-07-24 21:52:00

标签: c# asp.net-mvc automapper

我的下拉列表出现问题。我之前发布了这个:DropDownList not behaving as expected,但事情已经改变,所以我再次提交。

我有一个看起来像这样的视图模型:

public class CountryViewModel
{
    public int CountryId { get; set; }
    public string Text { get; set; }

    public IEnumerable<SelectListItem> Countries =
        new List<SelectListItem>
        {
            new SelectListItem {Value = "0", Text = "Select a country..."},
            new SelectListItem {Value = "1", Text = "US United States"},
            new SelectListItem {Value = "2", Text = "AF Afghanistan"},
            ...
        }
}

在我看来.cshtml:

<div class="col-lg-6 detail-right">
    @Html.DropDownListFor(m => m.LegalEntity.Address.Country.CountryId,
        new SelectList( Model.LegalEntity.Address.Country.Countries, 
            "Value", "Text",
            Model.LegalEntity.Address.Country.CountryId),
        new { @class = "form-control" })               
</div>

下拉列表会根据需要填充项目,并且正确的地址ID似乎正在发布到服务器。我认为问题出在AutoMapper上。控制器中的代码似乎是在视图模型中的每个国家/地区的国家/地区表中创建一个新行。它应该做的是在地址表中的外键中添加一个指向适当地址的值:

public ActionResult Create(SiteViewModel siteViewModel)
{
    if (ModelState.IsValid)
    {
        Site newSite = new Site();
        newSite = Mapper.Map<SiteViewModel, Site>(siteViewModel);
        newSite.DateCreated = DateTime.Now;
        _unitOfWork.SiteRepository.Insert(newSite);
        _unitOfWork.Save();
        ...
    }
}

如何让AutoMapper执行此操作?

标记

===更多信息===

我的SiteViewModel有一个AddressViewModel,如下所示:

public class SiteViewModel
{
    ...
    public virtual AddressViewModel Address { get; set; }
    ...
}

我的AddressViewModel如下所示:

public class AddressViewModel
{
    ...
    [Display(Name = "Country")]
    public virtual CountryViewModel Country { get; set; }
    ...
}

2 个答案:

答案 0 :(得分:0)

好的,所以我要在没有所有信息的情况下回答这个问题。

基本上,您将CountryViewModel映射到您的ORM期望的Country'domain对象。

AutoMapping基本上正在运行

new Country { Property = @value };

并创建一个未附加到ORM的新Country对象。您的ORM正在数据库中创建这些对象。

您要做的是使用ViewModel中的信息来查询数据库中的Country对象并在您的站点中使用它。类似于以下

public ActionResult Create(SiteViewModel siteViewModel)
{
    if (ModelState.IsValid)
    {
        Site newSite = new Site();
        newSite = Mapper.Map<SiteViewModel, Site>(siteViewModel);

        newSite.Address.Country = DbContext.Countries.FirstOrDefault(x => x.Id == siteViewModel.Address.Country.CountryId);

        newSite.DateCreated = DateTime.Now;
        _unitOfWork.SiteRepository.Insert(newSite);
        _unitOfWork.Save();
        ...
    }
}

这实际上提出了AutoMapper的原始设计不支持您在此尝试的内容。它是为了帮助支持将数据层投影到视图层对象中,而不是相反。

答案 1 :(得分:0)

您不想映射您的国家/地区对象,您只想映射国家/地区外键。因此,您需要向AutoMapper映射添加忽略规则,忽略Country对象映射。

您希望对在对象上具有导航属性的任何查找对象执行此操作。您不想添加新对象,只需插入现有外键即可。

但是,这假设您的视图模型与您的实体模型紧密相关。您可能需要展平CountryViewModel,忽略SelectList和Text,并将CountryId映射到Site对象中的CountryId Foreign键。如果您不使用单独的外键属性(即外键和导航属性),那么您将不得不做一些关于添加具有修改状态的Country对象,然后只映射Id。 / p>

很难提出建议,因为您还没有向我们提供此处重要对象的信息,即网站实体和国家/地区实体。你也没有给我们你的AutoMapper映射。