AutoMapper / AutoMapper.Collection

AutoMapper support for updating existing collections by equivalency
MIT License
245 stars 59 forks source link

Override GenerateEntityFrameworkPrimaryKeyPropertyMaps with EqualityComparison? #156

Closed jbhelm closed 2 years ago

jbhelm commented 3 years ago

I have some cases where the equality comparison GenerateEntityFrameworkPrimaryKeyPropertyMaps creates for some maps is incorrect. Namely they are child classes that have the parent ID as part of the primary key so EF actually deletes the entity instead of orphaning it. The source class doesn't have the parent ID. I've tried to override what GenerateEntityFrameworkPrimaryKeyPropertyMaps generates by calling CreateMap<>.EqualityComparison(), but it doesn't seem to have any effect. I've tried calling it both before and after the SetGeneratePropertyMaps() call, as well as calling it in a Profile class, but my EqualityComparison is always ignored and it appears the GenerateEntityFrameworkPrimaryKeyPropertyMaps takes priority.

Is there any way to override what GenerateEntityFrameworkPrimaryKeyPropertyMaps generates on a per-map basis? I'd like to avoid having to stop using GenerateEntityFrameworkPrimaryKeyPropertyMaps and manually calling EqualityComparison() on all the hundreds of maps.

Thanks!

TylerCarlson1 commented 3 years ago

EqualityComparison should override primary key generation, but you won't see the function being called in code to debug it unless you tie it into a function call.

When AM.Collection gets EqualityComparison it gets it as an expression of a function and not the function itself, so it will compile it somewhere else. If you make the expression call another function which actually does the comparison you can then debug through it and see what's going on. The method will get compiled to execute the function and you can debug it through the function at that point. Ex: CreateMap<src,dest>().EqualityComparison((s,d) => CatchBreakpointComparison(s,d)); NOTE: This won't work for Persist().InsertOrUpdate() at the top most parent level, since this expression can't be translated into T-SQL.

As far as the delete vs orphaning goes that's exactly how EntityFramework works. If you want to orphan child instead of deleting the only way to fix that is remove the ParentID from the Primary Key as it means the child is required to have a parent and can't be orphaned.

jbhelm commented 3 years ago

Thank you for the quick response! I'll have to dig deeper to see why it's not working in our case. It's good to know though that it "should" be working...