English 中文(简体)
AutoMapper 能否被“ 说服” 暂停特定绘图?
原标题:Can AutoMapper be "persuaded" to temporarily suspend particular mappings?

AutoMapper 能否被“ 说服” 暂停特定绘图?

为了说明要完成的工作,我将用一个插图来说明。假设我有一个存储库, < 坚固的> 学生存储库 , 使用 LINQ 与数据库对象(表)如学生、课程、活动、俱乐部等进行互动。 在应用程序方面,有匹配的域目标学生、课程、活动、俱乐部。 学生类包括类型课程、活动和俱乐部的阵列成员, 例如:

public class Student
{
    // ... more members
    public Course[] Courses { get; set; }
    public Activity[] Activities { get; set; }
    public Club[] Clubs { get; set; }
    // ... even more members
}

自动Mapper 被配置为将数据库对象映射到域对象的图象, 以在学生仓库的静态构建器中定义映射 :

public class StudentRepository : IStudentRepository
{
    static class StudentRepository
    {
        // ... other mappings

        Mapper.CreateMap<TableStudent, Student>()
            .ForMember(dest => dest.Courses, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Course>>(src.TableCourses)))
            .ForMember(dest => dest.Activities, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Activity>>(src.TableActivities)))
            .ForMember(dest => dest.Clubs, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Clubs>>(src.TableClubs)))
        // where TableStudents, TableCourses, TableActivities, TableClubs are database entities

        // ... yet more mappings

    }
}

“ persude” Automapp 能否在一个函数块内暂停映射? 例如 :

public Student[] GetStudents()
{
    DataContext dbContext = new StudentDBContext();

    var query = dbContext.Students;
    // => SUSPEND CONFIGURATION MAPPINGS for Subjects, Activities and Clubs WHILE STILL making use of others
    // => The idea here it to take personal charge of  manually  setting the particular members (*for some specific reasons)

    var students = Mapper.Map<Student>(query); // => Still be able to use AutoMapper to map other members
}

public Student[] OtherStudentRepositoryMethods()
{
    // Other repository methods continue to make use of the mappings configured in the static constructor
}

注意 "为某些具体原因 < 坚固> < / 坚固> : 人们可能想要从AutoMapper手中夺去控制权的原因之一是 < a href="http://codebbetter.com/davidhayden/2007/08/06/linq-to-sql-query-rapt-sql-sql-querios-to-breat-down-in-advanced-scenarios/ < a > 。 在 1 :n 社团中, LINQ 到 SQL 只支持加入 1:n 连接查询 < / strong > 。 AutoMapper在这里效率不高 - 向N 学生发出加载课程的呼声, 同一学生返回了装载活动的呼声, 并可能向同一学生返回的装载俱乐部发出更多呼声。

最佳回答

“ persude” Automapper 能否在一个功能区块内暂停映射?

据我所知,最好的方法就是 使用这种忽略( I)

public class StudentRepository : IStudentRepository
{
    static class StudentRepository
    {
        // ... other mappings

        Mapper.CreateMap<TableStudent, Student>()
            .ForMember(dest => dest.Courses, opt => opt.Ignore())
            .ForMember(dest => dest.Activities, opt => opt.Ignore())
            .ForMember(dest => dest.Clubs, opt => opt.Ignore())
        // where TableStudents, TableCourses, TableActivities, TableClubs are database entities

        // ... yet more mappings

    }
}

另外,正如以前所注意到的,我建议你为每一个目标使用不同的剖面图。这里举一个例子。

public BaseService()
{
    AutoMapperRegistry.Configure();
}

public class AutoMapperRegistry
{
    public static void Configure()
    {
        Mapper.Initialize(x =>
        {
            x.AddProfile<ServiceProfile1>();
            x.AddProfile<ServiceProfileReverseProfile1>();
        });
    }
}

public class ServiceProfile1 : Profile
{
    protected override string ProfileName
    {
        get
        {
            return "ServiceProfile1";
        }
    }

    protected override void Configure()
    {
        Mapper.CreateMap<DataContract_Sub, DTO_Sub>();
        Mapper.CreateMap<DataContract, DTO>()
            .ForMember(x => x.DataContract_Sub, opt => opt.MapFrom(y => y.DTO_Sub))
    .BeforeMap((s, d) => 
            {
                // your custom logic
            })
    .AfterMap((s, d) => 
            {
                // your custom logic
            });
    }
}
问题回答

实现这一点的方法之一是为每种情景分别创建绘图引擎实例,这样你就可以按照吉米·博加德关于以不同方式绘制单一类型图的回答中的建议,配置不同的地图。

感谢各位的反馈。 我花了时间来考虑所有的答案和建议。 没有什么特别能让问题变得非常好, 虽然他们提供了很多思考的食粮。 我认为我应该输入一些我尝试过的东西。 (< 强势> disabriter

public Student[] GetStudents()
{
    try
    { // Suspend/Ignore the mappings
        // => SUSPEND CONFIGURATION MAPPINGS for Subjects, Activities and Clubs
        Mapper.CreateMap<TableStudent, Student>()
                    .ForMember(dest => dest.Courses, opt => opt.Ignore())
                    .ForMember(dest => dest.Activities, opt => opt.Ignore())
                    .ForMember(dest => dest.Clubs, opt => opt.Ignore())

        DataContext dbContext = new StudentDBContext();

        var query = dbContext.Students;

        // other logic ...

        var students = Mapper.Map<Student>(query); // => Still be able to use AutoMapper to map other members
        // set the properties you needed to do manually
    }
    finally // Restore back the mappings
    {
        Mapper.CreateMap<TableStudent, Student>()
                    .ForMember(dest => dest.Courses, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Course>>(src.TableCourses)))
                    .ForMember(dest => dest.Activities, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Activity>>(src.TableActivities)))
                    .ForMember(dest => dest.Clubs, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Clubs>>(src.TableClubs)))
    }
}

正如我所提到的,它也许很脏。不是那种我高兴的代码,特别是因为我不知道如果CreateMap () () 在最后一块块内失败, 会出现什么特殊情形, 而是在一种遗留的应用程序上, 你可以对方法进行彻底修改—— 可能使用不同的描述, 就像上面的@Andriy Zakharko 所建议的那样, 你可以用它来暂时控制。 我亲自尝试过它。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签