简体   繁体   English

自动化多对多

[英]Automapper Many to Many

I've been trying to get this working for too long. 我一直试图让它工作太久。 I've looked at every automapper question I could find, but still no luck. 我查看了我能找到的每个自动播放器问题,但仍然没有运气。

How do I configure Automapper so that it will properly map my many to many properties between my business entity and my database model? 如何配置Automapper以便在我的业务实体和数据库模型之间正确映射多个属性?
I'm using a repository pattern using a DB first data model. 我正在使用DB第一个数据模型的存储库模式。

I have these entity objects: 我有这些实体对象:

 public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public DateTime CreateDate { get { return DateTime.Now; } private set { } }
    public List<Department> Departments { get; set; }
    public List<Company> Companies { get; set; }
}

  public class Department
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreateDate { get { return DateTime.Now; } private set { } }
}

public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreateDate { get { return DateTime.Now; } private set { } }
}

I need to be able to update these. 我需要能够更新这些。 I need to map them to the db object so I can update the user. 我需要将它们映射到db对象,以便我可以更新用户。

 public partial class User{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public Nullable<System.DateTime> CreateDate { get; set; }


    public virtual ICollection<UsersCompany> UsersCompanies { get; set; }

    public virtual ICollection<UsersDepartment> UsersDepartments { get; set; }
}

public partial class UsersCompany
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public int CompanyId { get; set; }

    public virtual Company Company { get; set; }
    public virtual User User { get; set; }
}

public partial class UsersDepartment
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public int DepartmentId { get; set; }

    public virtual Department Department { get; set; }
    public virtual User User { get; set; }
}

I have a method in which I pass the entity and attempt to map it to the db model. 我有一个方法,我传递实体并尝试将其映射到数据库模型。 This is what I have right now after about 100 different attempts to get automapper to politely map my join tables...with no luck. 这是我现在拥有的大约100次不同的尝试,以使automapper礼貌地映射我的连接表...没有运气。

private DBUser ToDataModel(User user)
    {

        var config = new MapperConfiguration(cfg =>
        {

            cfg.CreateMap<User, DBUser>()
            .ForMember(dest => dest.UsersDepartments, opt => opt.MapFrom(x => x.Departments));


            cfg.CreateMap<User, DBUsersDepartment>()
                .ForMember(x => x.User, y => y.MapFrom(z => z));


            cfg.CreateMap<Department, DBUsersDepartment>();


        });
        IMapper mapper = config.CreateMapper();

        return mapper.Map<DBUser>(user);
    }

This is what I see after it 'maps' (notice no user information has been mapped): 这是我在'maps'之后看到的(注意没有映射用户信息):

结果

You are mapping from 你正在映射

public class Department{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreateDate { get { return DateTime.Now; } private set { }
}

to

public partial class UsersDepartment{
    public int Id { get; set; }
    public int UserId { get; set; }
    public int DepartmentId { get; set; }

    public virtual Department Department { get; set; }//No matching property in Department
    public virtual User User { get; set; }//No matching property in Department

} }

so it is normal that when maping DepartmentUsersDepartment 所以当UsersDepartment DepartmentUsersDepartment是正常的

public virtual User User { get; set; } public virtual User User { get; set; } and public virtual Department Department { get; set; } public virtual User User { get; set; }public virtual Department Department { get; set; } public virtual Department Department { get; set; } public virtual Department Department { get; set; } will be null. public virtual Department Department { get; set; }将是空的。

Moreover, you are creating a mapper each time you call private DBUser ToDataModel(User user) , which is highly inefficient. 此外,每次调用private DBUser ToDataModel(User user)时,您都在创建映射器,这非常低效。 Please consider, creating your mappers at the beginning of your application, for example if it is web application in global.asax etc 请考虑在应用程序开始时创建映射器,例如,如果它是global.asax等中的Web应用程序

For anyone interested. 对任何感兴趣的人 I ended up going a different route, where I update each collection separately, then update the base user class. 我最终走了一条不同的路线,分别更新每个集合,然后更新基本用户类。 ...now off to the next issue. ......现在转到下一期。

If you still want to know a possible solution to your problem for the future, here are the necessary changes to your code, to get it to work. 如果您仍然想知道未来可能的问题解决方案,请对代码进行必要的更改,以使其能够正常运行。 While your DTO class User uses the direct related DTOs Department and Company, your DB class USerDb uses the many-many mappings UsersDepartment and UsersCompany. 当您的DTO类用户使用直接相关的DTO部门和公司时,您的数据库类USerDb使用许多映射UsersDepartment和UsersCompany。

public class User

{
...
public List<Department> Departments { get; set; }
public List<Company> Companies { get; set; }
}

public class DbUser
{
...
public List<UsersDepartment> UsersDepartments { get; set; }
public List<UsersCompany> UsersCompanies { get; set; }
}

cfg.CreateMap<UserDb, User>()
    .ForMember(dest => dest.Departments, opt => opt.MapFrom(user => user.UsersDepartments.Select(userDepartment => userDepartment.Department)))
    .ForMember(dest => dest.Companies, opt => opt.MapFrom(user => user.UsersCompanies.Select(userCompany => userCompany.Company)));


cfg.CreateMap<User,DbUser>()
    .ForMember(dest => dest.UsersDepartments, opt => opt.MapFrom( user=>user.Departments.Select( department=> new UsersDepartment{UserId=user.Id, DepartmentId=department.Id}))))
    .ForMember(dest => dest.UsersCompanies, opt => opt.MapFrom( user=>user.Companies.Select( company=> new UsersCompany{UserId=user.Id, CompanyId=company.Id}))));

I would also remove the additional Id from UsersDepartment and UsersCompany and use a combined key UsersId, DepartmentId or UseId,CompanyId instead. 我还会从UsersDepartment和UsersCompany中删除其他ID,并使用组合键UsersId,DepartmentId或UseId,CompanyId。

Hope, that helps. 希望,这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM