简体   繁体   中英

AutoMapper - mapping properties from one EF4 entity to another in a loop without Before/AfterMap

It appears that AutoMapper's methods BeforeMap and AfterMap have a critical bug, which if one is attempting to iterate over a collection of the source object to populate a property of the destination object, those mapping methods execute more than once. See: Extra iterations in a foreach in an AutoMapper map

What I'm trying to do is a bit complicated, so please bear with me.

I have a EF4 many-to-many graph (Games-to-Platforms) I'm trying to build based on incoming form data. In order to build the graph, I take the raw integer ids that come from the form, and then grab the correct Platforms from my repository in order to add them to the Game's collection. You can see my attempt at doing this within BeforeMap in the link I provided above.

The problem is that I'm not sure how to proceed. I need to be able to grab a hold of the destination (Game) object in order to successfully Add the Platforms to the Game. Is something like this possible in ForMember ? From what I've read, it doesn't look like a custom resolver would work for me, and I'm not sure how I'd implement a custom type converter given all the moving parts (two entities, repository).

Any ideas or suggestions?

I simply decided to make my own static mapper. Not an ideal, or even great solution, but it works. It can definitely be made more abstract, but I figure it's a band-aid until AutoMapper is fixed. My solution:

public static class GameMapper
{
    public static Game Map(IGameRepository repo, AdminGameEditModel formData, Game newGame)
    {
        newGame.GameID = formData.GameID;
        newGame.GameTitle = formData.GameTitle;
        newGame.GenreID = formData.GenreID;
        newGame.LastModified = DateTime.Now;
        newGame.ReviewScore = (short)formData.ReviewScore;
        newGame.ReviewText = formData.ReviewText;
        newGame.Cons = String.Join("|", formData.Cons);
        newGame.Pros = String.Join("|", formData.Pros);
        newGame.Slug = formData.Slug;

        if (newGame.Platforms != null && newGame.Platforms.Count > 0)
        {
            var oldPlats = newGame.Platforms.ToArray();

            foreach (var oldPlat in oldPlats)
            {
                newGame.Platforms.Remove(oldPlat);
            }
        }

        foreach (var platId in formData.PlatformIDs)
        {
            var plat = repo.GetPlatform(platId);
            newGame.Platforms.Add(plat);
        }

        return newGame;
    }
}

Unfortunately, I can't make the third parameter an out parameter due to my need to overwrite existing entity data during updating. Again, it's definitely not a pretty, or even good solution, but it does the job. I'm sure the OO gods will smite me at a later date.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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