Giter Site home page Giter Site logo

Comments (9)

TylerCarlson1 avatar TylerCarlson1 commented on July 4, 2024 1

Oh and you should look at #30 and #4. Basically it's EF is picky about removing objects from child collections and will either orphan or delete them.
If you just have ID as key it will try to orphan it by setting parent's ID to null, which will throw and exception. If you make ID and ParentID a composite primary key it will delete the object correctly. Also #4 is a workaround if you can't do that for whatever reason.

from automapper.collection.

TylerCarlson1 avatar TylerCarlson1 commented on July 4, 2024

Yes it does. Also the example you gave is for EF 4, so it might not be the exact same problem.

There's some issues I'm finding out with 5.x versions of AM and how mappings are made that could be causing problems. Was using 4.x for my biggest project till recently.

If you are using AM 5.x and AM.Collection 2.x then with create maps you'll have to call them twice. Once to make an IMapper, then set GenerateEntityFrameworkPrimaryKeyEquivilentExpressions using said mapper, then make the IMapper again and then it will create equivilancy exceptions. If you use Convention for this you don't have to double map, since the CreateMap will be called once you need it.

If you are using 4.x or changes asked above don't work, it might be something else with how you map or set up EF. Were you able to map back to EF from DTO using AM and manually updating the lists before?

#24 will fix this, along with be compatible with upcoming 5.3 which made a mapper collection change. The collection mapper adding and GenerateEntityFrameworkPrimaryKeyEquivilentExpressions will both be called in Initialize action for MapperConfiguration to solve this problem.

from automapper.collection.

maurosampietro avatar maurosampietro commented on July 4, 2024

I'm sorry i cannot make it work in any way

from automapper.collection.

TylerCarlson1 avatar TylerCarlson1 commented on July 4, 2024

Can't make your code it work or make an example to reproduce the problem?

from automapper.collection.

maurosampietro avatar maurosampietro commented on July 4, 2024

The situation is this

To solve that I tried this Automapper.Collection that introduced the problem described in this page. Trying to configure as you said (calling twice CreateMapper) did not help. Even without involving EF the original problem of updating an entity is not working for me.

I think I need a minimal complete example of a working configuration if you can provide it please.

from automapper.collection.

TylerCarlson1 avatar TylerCarlson1 commented on July 4, 2024

Here's a working example of your code with AM.Collections solving the update problem.

public class CollectionsTests
    {
        public class A
        {
            public List<B> Collection { get; set; }
        }

        public class A1
        {
            public List<B1> Collection { get; set; }
        }

        public class B
        {
            public int ID { get; set; }
            public string PropertyA { get; set; }
        }

        public class B1
        {
            public int ID { get; set; }
            public string PropertyA { get; set; }
            public string PropertyB { get; set; }
        }

        public void Collection_Map_Example()
        {
            var mapper = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<CollectionProfile>();
                cfg.CreateMap<A, A1>();
                cfg.CreateMap<B, B1>().EqualityComparision((b1, b) => b.ID == b1.ID);
            }).CreateMapper();

            var a = new A
            {
                Collection = new List<B>() {new B() {PropertyA = "c"}}
            };

            var a1 = new A1
            {
                Collection = new List<B1>() {new B1() {PropertyA = "a", PropertyB = "b"}}
            };
            mapper.Map(a, a1);
            a1.Collection.First().PropertyA.ShouldBeEquivalentTo("c");
            a1.Collection.First().PropertyB.ShouldBeEquivalentTo("b");
        }
    }

If you use AM.Collections.EF B1 would have ID as a key and explanation is in my first post goes over setting that up correctly.

If you are using anything other than EF 6.1.3 I don't support that and probably doesn't work.

from automapper.collection.

maurosampietro avatar maurosampietro commented on July 4, 2024

Thank you, at first glance it seems to work now.
I also had to update to EF 6.1.3.

Since all my entities have an ID I'm able to avoid EqualityComparison call by using EquivilentExpressions.GenerateEquality.Add( new GenerateEntityFrameworkPrimaryKeyEquivilentExpressions( _mapper ) );

Great.

The only thing I think I'm missing is to ignore B1.PropertyA so that the example should look like this:

 public void Collection_Map_Example()
        {
            var mapper = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<CollectionProfile>();
                cfg.CreateMap<A, A1>();
                cfg.CreateMap<B, B1>().ForMember( b => b.PropertyA, config => config.Ignore() );
            }).CreateMapper();

            var a = new A
            {
                Collection = new List<B>() {new B() {PropertyA = "c"}}
            };

            var a1 = new A1
            {
                Collection = new List<B1>() {new B1() {PropertyA = "a", PropertyB = "b"}}
            };
            mapper.Map(a, a1);
            a1.Collection.First().PropertyA.ShouldBeEquivalentTo("a"); // this fails
            a1.Collection.First().PropertyB.ShouldBeEquivalentTo("b");
        }

This works unless i use it directly with entities inside a DbContext.
Can you confirm the incorrect behavior?

from automapper.collection.

maurosampietro avatar maurosampietro commented on July 4, 2024

After a deeper look, i found out that records are not updated, are added every time a map is performed on the database.
I don't know exactly the context on which this happens. I'll give you more details but a question raises.. are you sure AM.Collections is designed to do a graph diff on EF?

Are there tests available?

from automapper.collection.

TylerCarlson1 avatar TylerCarlson1 commented on July 4, 2024

#24 adds test for EF equality comparisons. More specificly this. Note: The API is different than master (It solves the problem I discussed in my first comment on this thread)

Still have some other stuff to test, like Persist. But need to create an actual DB to test it.

For your example this should get it to work. (The issue I was talking about in first comment)

public void Collection_Map_Example()
        {
            var mapper = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<CollectionProfile>();
                cfg.CreateMap<A, A1>();
                cfg.CreateMap<B, B1>().ForMember( b => b.PropertyA, config => config.Ignore() );
            }).CreateMapper();

            // Set up expressions to use the first mapping to make the equivalent expressions
            EquivilentExpressions.GenerateEquality.Add( new GenerateEntityFrameworkPrimaryKeyEquivilentExpressions<MyDBContext>( _mapper ) );

             // Re-Create Mapper this time it will update the lists properly
            mapper = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<CollectionProfile>();
                cfg.CreateMap<A, A1>();
                cfg.CreateMap<B, B1>().ForMember( b => b.PropertyA, config => config.Ignore() );
            }).CreateMapper();

            var a = new A
            {
                Collection = new List<B>() {new B() {PropertyA = "c"}}
            };

            var a1 = new A1
            {
                Collection = new List<B1>() {new B1() {PropertyA = "a", PropertyB = "b"}}
            };
            mapper.Map(a, a1);
            a1.Collection.First().PropertyA.ShouldBeEquivalentTo("a"); // this fails
            a1.Collection.First().PropertyB.ShouldBeEquivalentTo("b");
        }

from automapper.collection.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.