【问题标题】:Using Automapper to map entity framework classes to business classes使用 Automapper 将实体框架类映射到业务类
【发布时间】:2016-07-08 14:05:57
【问题描述】:

我有以下两个实体框架生成的类:

public partial class Person
{
    public int id { get; set; }
    public string namen { get; set; }
    public int house { get; set; }
    [IgnoreMap]
    public virtual House House1 { get; set; }
}

public partial class House
{
    public House()
    {
        this.Persons = new HashSet<Person>();
    }
    public int id { get; set; }
    public string street { get; set; }
    public string city { get; set; }
    public ICollection<Person> Persons { get; set; }
}

那么我的业务层中也有这两个类似的类:

public class House
{        
    public House()
    {
        this.Persons = new HashSet<Person>();
    }
    public int id { get; set; }
    public string street { get; set; }
    public string city { get; set; }        
    public virtual ICollection<Person> Persons { get; set; }
}

public class Person
{
    public int id { get; set; }
    public string namen { get; set; }
    public int house { get; set; }        
}

几乎一样,休? 在我的业务层中,我从数据库中读取了房屋列表。然后我使用 Automapper 将整个列表映射到我的 Business house 类列表:

    public List<elci.BusinessEntities.House> getHouses()
    {
        YardEntities cx = new YardEntities();
        Mapper.Initialize(cfg => cfg.CreateMap<DataAccessLayer.House, BusinessEntities.House>());

        List<DataAccessLayer.House> dhl = cx.Houses.ToList();
        List<BusinessEntities.House> bhl = Mapper.Map<List<DataAccessLayer.House>, List<BusinessEntities.House>>(dhl);
        return bhl;
    }

但是,在以下行中,我得到了一个运行时异常:

 Mapper.Map<List<DataAccessLayer.House>, List<BusinessEntities.House>>(dhl);

“错误映射类型”。

我想,这可能是因为每个人都指向一个房子,每个房子都指向一个人。因为我的 BusinessLayer 中不需要这个“圆圈”,所以我用 [IgnoreMap] 修饰了这个属性,但没有任何成功。错误仍然存​​在。

任何建议我做错了什么?

【问题讨论】:

  • 如果您删除 IgnoreMap 属性。有效吗?
  • Error Mapping Types 错误还给出了未映射的类型。你能进入内部异常细节并粘贴到这里吗?
  • 另外,您需要为Person 实体显式创建mapper,因为它们在House 实体中被引用。

标签: c# asp.net .net entity-framework automapper


【解决方案1】:

所以这最终解决了我的问题:

        Mapper.Initialize(cfg => {
            cfg.CreateMap<List<House>, List<HouseViewModel>>();
            cfg.CreateMap<List<Person>, List<PersonViewModel>>();
        });

【讨论】:

    【解决方案2】:

    是的,错误仍然没有忽略映射。 内部异常告诉我以下内容:

    {"Error mapping types.\r\n\r\nMapping types:\r\nList`1 -> List`1\r\nSystem.Collections.Generic.List`1[[elci.DataAccessLayer.House, DataAccessLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> System.Collections.Generic.List`1[[elci.BusinessEntities.House, BusinessEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
    

    所以房子类型是问题所在。 我还尝试添加另一张地图:

            Mapper.Initialize(cfg => cfg.CreateMap<DataAccessLayer.House, BusinessEntities.House>());
            Mapper.Initialize(cfg => cfg.CreateMap<DataAccessLayer.Person, BusinessEntities.Person>());
    

    没有成功和同样的错误。 :-(

    【讨论】:

      【解决方案3】:

      尝试使用

      config.CreateMap<TSource,TDestination>().PreserveReferences()
      

      你有循环引用 Person->House->ICollection

      循环引用

      以前,AutoMapper 可以通过跟踪映射的内容来处理循环引用,并且在每次映射时,检查源/目标对象的本地哈希表以查看项目是否已被映射。事实证明,这种跟踪非常昂贵,您需要选择使用 PreserveReferences 才能使圆形地图工作。或者,您可以配置 MaxDepth:

      // Self-referential mapping
      cfg.CreateMap<Category, CategoryDto>().MaxDepth(3);
      // Circular references between users and groups
      cfg.CreateMap<User, UserDto>().PreserveReferences();
      

      AutoMapper docs

      【讨论】:

      • 由于链接可能中断,请在答案中包含链接页面的相关部分。
      • 不再需要了。文档继续Starting from 6.1.0 PreserveReferences is set automatically at config time whenever the recursion can be detected statically.
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-18
      • 2015-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多