Add remove items to existing collection mappings #528

Closed
wants to merge 14 commits into
from

Conversation

Projects
None yet
2 participants
@TylerCarlson1
Member

TylerCarlson1 commented May 25, 2014

New mapper that will map IEnumerable to ICollection<> types, IFF both are not null and have equivalency expression assigned to them. Equivalency expressions will be used to Add/Modify/Delete objects within a collection.
Added to all mappers after read only collection mapper as to not attempt on read only collections.

Included Extension method for creating custom comparisons in the CreateMap<TSource,TDest> fluent API. (Unit test added in unit tests)
Ability to add custom equivalency expression conventions that will generate equivalencies based on source and dest type.
Added EntityFramework primary key example in Automapper.EntityFramework project. Unit test in Integrations test project.
EntityFramwork's mapping are overwritten by custom mappings.

Set up so other ORMs can be used as long as you can ascertain the PK's of each object by their types.

I want to include further conventions on top of PKs like override key mappings, but this shows the default implementation that should work for most cases.

TylerCarlson1 added some commits May 24, 2014

Class compare for list mappings
Add comparison lambda between 2 classes
Compare Update
Update for EF
Updated Unit Tests and Refactored Code
Made things more readable

@jbogard jbogard added this to the 3.3.0 milestone May 28, 2014

@jbogard

This comment has been minimized.

Show comment Hide comment
@jbogard

jbogard May 28, 2014

Owner

Cool stuff! Lot of people have been asking for this.

Owner

jbogard commented May 28, 2014

Cool stuff! Lot of people have been asking for this.

Updated PropertyInfo conventions to use PropertyMaps instead.
Now ForMember statements will be used to compare the source and destination if applied.  Default conventions still apply.
Examples:
-ForMember going to different property which name won't match will use that as an equivalent value
-ForMember using something other than just a property to match (sub properties, arithmetic, sub functions)

Issues with using it now (Don't have a scenario why someone might run into this but it's still possible)
Equality assumes both values are of the same type and simple types
-If complex type equality won't work because it will default to equals
-If properties are different and have another type map, will get an exception and mapping will default to can't convert
Way to fix would be to add recursion into the equivalency expression so that if source and destination don't have same type, return a new equivalency statement to be added to the parent comparison
@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 May 29, 2014

Member

Updated the code.

It is more versatile by using PropertyMaps instead of PropertyInfo convention.
ForMember statements will now be used if the destination property is being used for equivalency

Edit: Git missed some changes to the update.(Solution would not compile) Pushed them up now.

Member

TylerCarlson1 commented May 29, 2014

Updated the code.

It is more versatile by using PropertyMaps instead of PropertyInfo convention.
ForMember statements will now be used if the destination property is being used for equivalency

Edit: Git missed some changes to the update.(Solution would not compile) Pushed them up now.

Updated PropertyInfo conventions to use PropertyMaps instead.
Now ForMember statements will be used to compare the source and destination if applied.  Default conventions still apply.
Examples:
-ForMember going to different property which name won't match will use that as an equivalent value
-ForMember using something other than just a property to match (sub properties, arithmetic, sub functions)

Issues with using it now (Don't have a scenario why someone might run into this but it's still possible)
Equality assumes both values are of the same type and simple types
-If complex type equality won't work because it will default to equals
-If properties are different and have another type map, will get an exception and mapping will default to can't convert
Way to fix would be to add recursion into the equivalency expression so that if source and destination don't have same type, return a new equivalency statement to be added to the parent comparison
@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 May 30, 2014

Member

I was wondering if there were other scenarios that this might have to encompass.

My solution was to solve the issues with scaling with saving mapping classes with children and their children's children.
Good Example in URL below.
http://rogeralsing.com/2013/12/01/why-mapping-dtos-to-entities-using-automapper-and-entityframework-is-horrible/

As long as you add the DBContext to the EF objects are based on, then worrying about adding/updating/deleting becomes trivial. All you have to do is map the children collections to each other and it handles the nitty gritty behind the scenes. (Except for when EF orphens children, which I found adding the FK property as an addition to the PK will properly remove it when you delete from the parent)

The only thing it doesn't do is the initial comparison of the baseDTO vs the base EF object (So you could do a general Save and Delete instead of Add/Insert and Delete, but check for uniqueness before so).

I can add that, but I don't know if it falls into automapper's scope. The only use I can see is It would be used as Map<BaseDTO,Expression<Func<Base,bool>>>(baseToSave) and then EF will be able to convert that to a T-SQL statement that can be used to get the equivalent base object if it exists.

Also I was wondering if equivalency needs to use things besides the property maps. Like account for before maps, after maps, user inputed convert using functions, ect.

Member

TylerCarlson1 commented May 30, 2014

I was wondering if there were other scenarios that this might have to encompass.

My solution was to solve the issues with scaling with saving mapping classes with children and their children's children.
Good Example in URL below.
http://rogeralsing.com/2013/12/01/why-mapping-dtos-to-entities-using-automapper-and-entityframework-is-horrible/

As long as you add the DBContext to the EF objects are based on, then worrying about adding/updating/deleting becomes trivial. All you have to do is map the children collections to each other and it handles the nitty gritty behind the scenes. (Except for when EF orphens children, which I found adding the FK property as an addition to the PK will properly remove it when you delete from the parent)

The only thing it doesn't do is the initial comparison of the baseDTO vs the base EF object (So you could do a general Save and Delete instead of Add/Insert and Delete, but check for uniqueness before so).

I can add that, but I don't know if it falls into automapper's scope. The only use I can see is It would be used as Map<BaseDTO,Expression<Func<Base,bool>>>(baseToSave) and then EF will be able to convert that to a T-SQL statement that can be used to get the equivalent base object if it exists.

Also I was wondering if equivalency needs to use things besides the property maps. Like account for before maps, after maps, user inputed convert using functions, ect.

DTOToEquivilentExpression
As well a Expression to Expression of different type

@jbogard jbogard added the Feature label Jun 6, 2014

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jun 6, 2014

Member

Added changes for DTO object to Expression<Func<EFObject,bool>> and Expression conversion using property maps because I noticed it applies to issue #294.
Just takes the property mappings and converts property expressions of one type to another using their property values. There is no error checking for UnaryExpressions or any other type. If you include them it won't translate, and EF definetly can't convert it to a T-SQL statement.

Also included is DBRepository which uses both to do a general Save(DTO).

Member

TylerCarlson1 commented Jun 6, 2014

Added changes for DTO object to Expression<Func<EFObject,bool>> and Expression conversion using property maps because I noticed it applies to issue #294.
Just takes the property mappings and converts property expressions of one type to another using their property values. There is no error checking for UnaryExpressions or any other type. If you include them it won't translate, and EF definetly can't convert it to a T-SQL statement.

Also included is DBRepository which uses both to do a general Save(DTO).

TylerCarlson TylerCarlson
Refactored Expression to Expression mapper to use equivalency express…
…ion system, from 2 objects and then convert all properties from one type to a constant value from the object.

Issue is expression was chached with the first object used and wouldn't change.
Added ability to convert flattened properties.

Changed mapping using property maps to use property values explicitly instead of pointing to a function that would return the value.
Since using these as the base of Expression to expression for entity framework, it can't figure out uses for invoke and convert.
@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jun 19, 2014

Member

Fixed some errors that were caused by DTO to Object Expression mappings. It now uses Equality Expressions as a base, so custom equivalency expressions can be used for object to Expression mappings, along with the database generated mappings.

Original AddRemove's Equivalency expression now uses property maps to convert the lambda expressions vs using functions that just get the value. This way they are convertable to Database models like Entity Framework.

Object to Expression and Expression to Expression are added into the AllMappers base now.
With this there is no need to add database specific mappings to the AllMappers list. But you still need to add the equivalencyexpression rules so that they can be used for mappings.

Also added flattening so expression to expression can convert baseDTO.SubProp == 4 to base.Sub.Prop == 4.

Member

TylerCarlson1 commented Jun 19, 2014

Fixed some errors that were caused by DTO to Object Expression mappings. It now uses Equality Expressions as a base, so custom equivalency expressions can be used for object to Expression mappings, along with the database generated mappings.

Original AddRemove's Equivalency expression now uses property maps to convert the lambda expressions vs using functions that just get the value. This way they are convertable to Database models like Entity Framework.

Object to Expression and Expression to Expression are added into the AllMappers base now.
With this there is no need to add database specific mappings to the AllMappers list. But you still need to add the equivalencyexpression rules so that they can be used for mappings.

Also added flattening so expression to expression can convert baseDTO.SubProp == 4 to base.Sub.Prop == 4.

TylerCarlson added some commits Jun 19, 2014

TylerCarlson TylerCarlson
Refactored Expression to Expression mapper to use equivalency express…
…ion system, from 2 objects and then convert all properties from one type to a constant value from the object.

Issue is expression was chached with the first object used and wouldn't change.
Added ability to convert flattened properties.

Changed mapping using property maps to use property values explicitly instead of pointing to a function that would return the value.
Since using these as the base of Expression to expression for entity framework, it can't figure out uses for invoke and convert.
@jbogard

This comment has been minimized.

Show comment Hide comment
@jbogard

jbogard Jun 20, 2014

Owner

Is this OK to merge? Or is there still items to be added?

Owner

jbogard commented Jun 20, 2014

Is this OK to merge? Or is there still items to be added?

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jun 20, 2014

Member

I've added all the features I set out to achieve. The only things left are possibly tweaking the names of classes functions, exception messages, so they are in line with the rest of AutoMapper. I don't know what would be best suited so, I would leave that up to you to decide.

I don't know if you would make those changes here or merge and make new pull requests for it or what.

Still new to Git and the flow of things in the open source community

Member

TylerCarlson1 commented Jun 20, 2014

I've added all the features I set out to achieve. The only things left are possibly tweaking the names of classes functions, exception messages, so they are in line with the rest of AutoMapper. I don't know what would be best suited so, I would leave that up to you to decide.

I don't know if you would make those changes here or merge and make new pull requests for it or what.

Still new to Git and the flow of things in the open source community

@jbogard

This comment has been minimized.

Show comment Hide comment
@jbogard

jbogard Jun 23, 2014

Owner

Ah, the exceptions I can futz with. I just wanted to make sure before I
merged that you were "done" with this feature, and the addition of commits
to a pull request is an indication that it's not ready to merge. If it is,
I can merge it in no problem!

On Fri, Jun 20, 2014 at 12:52 PM, Tyler Carlson notifications@github.com
wrote:

I've added all the features I set out to achieve. The only things left are
possibly tweaking the names of classes functions, exception messages, so
they are in line with the rest of AutoMapper. I don't know what would be
best suited so, I would leave that up to you to decide.

I don't know if you would make those changes here or merge and make new
pull requests for it or what.

Still new to Git and the flow of things in the open source community


Reply to this email directly or view it on GitHub
#528 (comment).

Owner

jbogard commented Jun 23, 2014

Ah, the exceptions I can futz with. I just wanted to make sure before I
merged that you were "done" with this feature, and the addition of commits
to a pull request is an indication that it's not ready to merge. If it is,
I can merge it in no problem!

On Fri, Jun 20, 2014 at 12:52 PM, Tyler Carlson notifications@github.com
wrote:

I've added all the features I set out to achieve. The only things left are
possibly tweaking the names of classes functions, exception messages, so
they are in line with the rest of AutoMapper. I don't know what would be
best suited so, I would leave that up to you to decide.

I don't know if you would make those changes here or merge and make new
pull requests for it or what.

Still new to Git and the flow of things in the open source community


Reply to this email directly or view it on GitHub
#528 (comment).

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jun 23, 2014

Member

Yes I'm done with the feature then.
Just gotta wait and see what people use it for and go from there.

Member

TylerCarlson1 commented Jun 23, 2014

Yes I'm done with the feature then.
Just gotta wait and see what people use it for and go from there.

@jbogard

This comment has been minimized.

Show comment Hide comment
@jbogard

jbogard Jun 23, 2014

Owner

So a couple of things I think I'm going to change here. First, I'd like to have the configuration related to maps, stored on those maps, so instead of locating equivalent expressions, I'd just include it on the TypeMap. Second, what's the purpose of using an Expression rather than a Func? You have to compile the expression to execute it, and if you just had a Func it would just work. Finally, just to confirm, you couldn't modify the existing CollectionMapper because it only added etc?

Owner

jbogard commented Jun 23, 2014

So a couple of things I think I'm going to change here. First, I'd like to have the configuration related to maps, stored on those maps, so instead of locating equivalent expressions, I'd just include it on the TypeMap. Second, what's the purpose of using an Expression rather than a Func? You have to compile the expression to execute it, and if you just had a Func it would just work. Finally, just to confirm, you couldn't modify the existing CollectionMapper because it only added etc?

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jun 23, 2014

Member

I'm not sure how you would associate it to the type map. Because one type map can have multiple equivalency expressions each to a different object type, and the way it's setup is so that you have to search to see if one exists if it's not already searched for.
PS: This is not just for User defined expressions, but for conventions like Entity Framework's primary keys to determine equivalency.
Other way you could do it is get all equivalency expressions at once, but then you are following up every possibility even if it isn't included in an enumerable mapping, unless you want to filter those out. So what I did was cache them as they are called. If you try mapping again and there is no equivalency, then the system already knows you tried with a bad equivalency value and you don't go searching for it again.

As for the expression I did that because I wanted this to be used as part of EF, which needs Expressions not functions. That's for things like baseDTO -> Expression<Func<base,bool>>, and the expression visitor was a good way to translate the property maps easily. I translate it from Expression<Func<baseDTO,base,bool>> and convert all baseDTO mappings to constant value from the object passed over. That way user defined expressions can be used for determining equivalency between DTO and EF object, which I use in one of my projects. EX: DB to DB transfer where both tables have Auto Incriminating ID columns, and need linking table between the two to know which one matches up to the other.

As for the collection mapper I didn't use it because it goes on the principle that final is a collection and not whether it exists or not. For mine I only wanted it to map if the destination wasn't null, because if I had to create it, then there's no point to comparing something to nothing. Also I wanted an extra condition that the equivalency existed between the two objects, because if I don't have that I have nothing to compare to and you revert back to standard collection mapping.

To kind of sum it all up, these mappings work on can you get an equivalent expression from 2 different types and if you can then it's mappable, if not then it isn't.

If you have any more questions about this, and how it's used or what it's purpose is for please ask.
I know this is a huge feature.

Member

TylerCarlson1 commented Jun 23, 2014

I'm not sure how you would associate it to the type map. Because one type map can have multiple equivalency expressions each to a different object type, and the way it's setup is so that you have to search to see if one exists if it's not already searched for.
PS: This is not just for User defined expressions, but for conventions like Entity Framework's primary keys to determine equivalency.
Other way you could do it is get all equivalency expressions at once, but then you are following up every possibility even if it isn't included in an enumerable mapping, unless you want to filter those out. So what I did was cache them as they are called. If you try mapping again and there is no equivalency, then the system already knows you tried with a bad equivalency value and you don't go searching for it again.

As for the expression I did that because I wanted this to be used as part of EF, which needs Expressions not functions. That's for things like baseDTO -> Expression<Func<base,bool>>, and the expression visitor was a good way to translate the property maps easily. I translate it from Expression<Func<baseDTO,base,bool>> and convert all baseDTO mappings to constant value from the object passed over. That way user defined expressions can be used for determining equivalency between DTO and EF object, which I use in one of my projects. EX: DB to DB transfer where both tables have Auto Incriminating ID columns, and need linking table between the two to know which one matches up to the other.

As for the collection mapper I didn't use it because it goes on the principle that final is a collection and not whether it exists or not. For mine I only wanted it to map if the destination wasn't null, because if I had to create it, then there's no point to comparing something to nothing. Also I wanted an extra condition that the equivalency existed between the two objects, because if I don't have that I have nothing to compare to and you revert back to standard collection mapping.

To kind of sum it all up, these mappings work on can you get an equivalent expression from 2 different types and if you can then it's mappable, if not then it isn't.

If you have any more questions about this, and how it's used or what it's purpose is for please ask.
I know this is a huge feature.

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jun 23, 2014

Member

Also if you look at DBRepository.cs that is an example of what I want to achieve.
It's a repository where you can save a DTO object and tell it to go to its DB equivilent and it will handle, the insert or update logic, then save it, and all it's child classes without you having to write any boilerplate code to determine inserts/updates/deletes on ANYTHING. Just make sure your DB is correctly done and that the DTOs have mappings to all the Key properties and it will correctly save and delete any DTO you pass into it.

It essentialy fixes the issue of this article below, turning saving and deleting into a trivial matter.
http://rogeralsing.com/2013/12/01/why-mapping-dtos-to-entities-using-automapper-and-entityframework-is-horrible/

Also sorry for not using Project().To(), code has child tables which currently Project doesn't support.

Member

TylerCarlson1 commented Jun 23, 2014

Also if you look at DBRepository.cs that is an example of what I want to achieve.
It's a repository where you can save a DTO object and tell it to go to its DB equivilent and it will handle, the insert or update logic, then save it, and all it's child classes without you having to write any boilerplate code to determine inserts/updates/deletes on ANYTHING. Just make sure your DB is correctly done and that the DTOs have mappings to all the Key properties and it will correctly save and delete any DTO you pass into it.

It essentialy fixes the issue of this article below, turning saving and deleting into a trivial matter.
http://rogeralsing.com/2013/12/01/why-mapping-dtos-to-entities-using-automapper-and-entityframework-is-horrible/

Also sorry for not using Project().To(), code has child tables which currently Project doesn't support.

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jun 24, 2014

Member

I know this solution is heavily skewed towards Entity Framework and its problems, but I'm hoping it's generic enough to work with other ORMs like NHibernate. I've looked around and I know they are similar in how they both use expressions trees, but as far as what benefit it could provide to the framework as a whole I'm not sure, since I'm not failure with its best practices and intricacies.

Member

TylerCarlson1 commented Jun 24, 2014

I know this solution is heavily skewed towards Entity Framework and its problems, but I'm hoping it's generic enough to work with other ORMs like NHibernate. I've looked around and I know they are similar in how they both use expressions trees, but as far as what benefit it could provide to the framework as a whole I'm not sure, since I'm not failure with its best practices and intricacies.

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jun 26, 2014

Member

Looking back on my first comment I realized you could associate it to a type map if you wanted.

"I'm not sure how you would associate it to the type map. Because one type map can have multiple equivalency expressions each to a different object type, and the way it's setup is so that you have to search to see if one exists if it's not already searched for." This is incorrect statement, I meant that one type can have multiple equivalency expressions to other types, but that can still be used as the base implementation and still have the type map just wrap around it.

What you could do is make a function call in TypeMap like so

public IEquivilentExpression EquivilentExpression()
{
      return EquivilentExpressions.GetEquivilentExpression(SourceType, DestinationType);
}

but then you have to spend extra time trying to find the TypeMap from source and destination type of the Expression, which is wasted since you can get it directly using source and destination type.

When I made this I didn't want to try to alter any of the existing code's, and just add onto the existing framework. Actually I had a working version of this outside the framework, but I thought it was so useful, that there was a great benefit to including it with Automapper.
I did that by adding new IObjectMappers that had their own uses that didn't interfere with existing functionality. Especially the TypeMap class, since it seems to have so much functionality doing a variety of things packed into it already.

Member

TylerCarlson1 commented Jun 26, 2014

Looking back on my first comment I realized you could associate it to a type map if you wanted.

"I'm not sure how you would associate it to the type map. Because one type map can have multiple equivalency expressions each to a different object type, and the way it's setup is so that you have to search to see if one exists if it's not already searched for." This is incorrect statement, I meant that one type can have multiple equivalency expressions to other types, but that can still be used as the base implementation and still have the type map just wrap around it.

What you could do is make a function call in TypeMap like so

public IEquivilentExpression EquivilentExpression()
{
      return EquivilentExpressions.GetEquivilentExpression(SourceType, DestinationType);
}

but then you have to spend extra time trying to find the TypeMap from source and destination type of the Expression, which is wasted since you can get it directly using source and destination type.

When I made this I didn't want to try to alter any of the existing code's, and just add onto the existing framework. Actually I had a working version of this outside the framework, but I thought it was so useful, that there was a great benefit to including it with Automapper.
I did that by adding new IObjectMappers that had their own uses that didn't interfere with existing functionality. Especially the TypeMap class, since it seems to have so much functionality doing a variety of things packed into it already.

@jbogard

This comment has been minimized.

Show comment Hide comment
@jbogard

jbogard Jun 26, 2014

Owner

The thing about a TypeMap is that it contains all configuration for mapping one type to another, so it's OK if it gets big, you can always move the implementation out of it (like value resolvers), but leave the instructions inside. Plus it allows you to get rid of some static dictionaries - which I've had to limit because of thread safety issues.

Owner

jbogard commented Jun 26, 2014

The thing about a TypeMap is that it contains all configuration for mapping one type to another, so it's OK if it gets big, you can always move the implementation out of it (like value resolvers), but leave the instructions inside. Plus it allows you to get rid of some static dictionaries - which I've had to limit because of thread safety issues.

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jun 26, 2014

Member

I can see there being thread safe issues with creating and caching convention based expressions as you need them during run time.

Ok if that is the case, you might just be able to lazy load the Equivalency Expression, and remove all static Dictionaries caching the values.
Like in GenerateEquivilentExpressionsBasedOnGeneratePropertyMaps.cs Line 10.

private Lazy<IEquivilentExpression> _lazyEquivilentExpression = new Lazy<IEquivilentExpression>(() => EquivilentExpressions.GetEquivilentExpression(SourceType, DestinationType));
public IEquivilentExpression EquivilentExpression()
{
    return _lazyEquivilentExpression.Value;
}

For UserDefinedEquivilentExpressions I don't know if you need to make that thread safe, since it should be constructed during configuration time, which should be done in a single thread. And when determining if it exists, it wouldn't be modifying anything, just accessing.

Also GenerateEquivilentExpressionsBasedOnGeneratePropertyMaps probably needs to call generatePropertyMaps in a thread safe enviroment, so the user doesn't have to worry about making it thread safe if he wants to make his own property map conventions.

There might be a few others but those are the biggest thread safety issues I can see occurring.

Member

TylerCarlson1 commented Jun 26, 2014

I can see there being thread safe issues with creating and caching convention based expressions as you need them during run time.

Ok if that is the case, you might just be able to lazy load the Equivalency Expression, and remove all static Dictionaries caching the values.
Like in GenerateEquivilentExpressionsBasedOnGeneratePropertyMaps.cs Line 10.

private Lazy<IEquivilentExpression> _lazyEquivilentExpression = new Lazy<IEquivilentExpression>(() => EquivilentExpressions.GetEquivilentExpression(SourceType, DestinationType));
public IEquivilentExpression EquivilentExpression()
{
    return _lazyEquivilentExpression.Value;
}

For UserDefinedEquivilentExpressions I don't know if you need to make that thread safe, since it should be constructed during configuration time, which should be done in a single thread. And when determining if it exists, it wouldn't be modifying anything, just accessing.

Also GenerateEquivilentExpressionsBasedOnGeneratePropertyMaps probably needs to call generatePropertyMaps in a thread safe enviroment, so the user doesn't have to worry about making it thread safe if he wants to make his own property map conventions.

There might be a few others but those are the biggest thread safety issues I can see occurring.

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Jul 17, 2014

Member

Any updates on this?

Member

TylerCarlson1 commented Jul 17, 2014

Any updates on this?

@jbogard

This comment has been minimized.

Show comment Hide comment
@jbogard

jbogard Sep 12, 2014

Owner

So I was going through the process of merging, but I think it needs a little bit more refinement. I'm gonna table this for 3.3 and put it on the docker for 3.4, I like your approach, I just want a little more time to think about it.

Owner

jbogard commented Sep 12, 2014

So I was going through the process of merging, but I think it needs a little bit more refinement. I'm gonna table this for 3.3 and put it on the docker for 3.4, I like your approach, I just want a little more time to think about it.

@jbogard jbogard modified the milestones: v.Future, 3.3.0 Sep 12, 2014

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Sep 12, 2014

Member

Ok then.

I understand it is its own thing and needs to have a new feature explanation of how to use it and all. I certainly haven't written a detailed enough plan how to use it.

And there are still feature decisions that haven't been addressed. How to use PKs as comparisons from EF, NHibernate, LinqToSQL, ect. with the fact that you HAVE to reference them in order to make a dll for it.

It's still a general working concept at the point the pull request is right now.

Member

TylerCarlson1 commented Sep 12, 2014

Ok then.

I understand it is its own thing and needs to have a new feature explanation of how to use it and all. I certainly haven't written a detailed enough plan how to use it.

And there are still feature decisions that haven't been addressed. How to use PKs as comparisons from EF, NHibernate, LinqToSQL, ect. with the fact that you HAVE to reference them in order to make a dll for it.

It's still a general working concept at the point the pull request is right now.

@jbogard

This comment has been minimized.

Show comment Hide comment
@jbogard

jbogard Sep 12, 2014

Owner

I think what I'm going to do here is pull in the parts that are just about comparisons, but leave the EF stuff part out. I've been meaning to pull the IDataReader stuff out of the core libraries, so for this I'd create a separate library AND repo for EF extensions. That way the extensions library can be versioned independently of the core library.

Owner

jbogard commented Sep 12, 2014

I think what I'm going to do here is pull in the parts that are just about comparisons, but leave the EF stuff part out. I've been meaning to pull the IDataReader stuff out of the core libraries, so for this I'd create a separate library AND repo for EF extensions. That way the extensions library can be versioned independently of the core library.

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Sep 12, 2014

Member

After looking more into using DBContext as unit of work, I think it might be worth changing IDBRepository's Save and Delete calls and turning them into extension methods off of IDbSet. Maybe something like Set<T>().Persist().From<TDTO>(TDTO toPersist) and Set<T>().Remove().From<TDTO>(TDTO toRemove) and just not submit changes. Could be a nice all in one method to compliment Project().To<TDTO>().

Member

TylerCarlson1 commented Sep 12, 2014

After looking more into using DBContext as unit of work, I think it might be worth changing IDBRepository's Save and Delete calls and turning them into extension methods off of IDbSet. Maybe something like Set<T>().Persist().From<TDTO>(TDTO toPersist) and Set<T>().Remove().From<TDTO>(TDTO toRemove) and just not submit changes. Could be a nice all in one method to compliment Project().To<TDTO>().

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Oct 28, 2014

Member

Updated Pull Request with merged changes from development, along with removing AutoMapper.Entityframework from the solution. AutoMapper.EntityFramework is temporarily in it's own repository at https://github.com/TylerCarlson1/AutoMapper.EntityFramework/tree/master/src/AutoMapper.EntityFramework

This repo is referencing automapper Net4 build in the debug folder, for now.
Also added Persist().To<TFrom>() to it, along with comments for public functions.
Feel free to fork and make it part of AutoMapper.EF as primary repository if you so wish. Or just make your own and copy the code over, whatever works best.

Also removed ExpressionToExpresison mapper from pull because it was already in from #584 and #294.

Member

TylerCarlson1 commented Oct 28, 2014

Updated Pull Request with merged changes from development, along with removing AutoMapper.Entityframework from the solution. AutoMapper.EntityFramework is temporarily in it's own repository at https://github.com/TylerCarlson1/AutoMapper.EntityFramework/tree/master/src/AutoMapper.EntityFramework

This repo is referencing automapper Net4 build in the debug folder, for now.
Also added Persist().To<TFrom>() to it, along with comments for public functions.
Feel free to fork and make it part of AutoMapper.EF as primary repository if you so wish. Or just make your own and copy the code over, whatever works best.

Also removed ExpressionToExpresison mapper from pull because it was already in from #584 and #294.

@jbogard

This comment has been minimized.

Show comment Hide comment
@jbogard

jbogard Oct 31, 2014

Owner

So the reason this is taking a while to merge is that I've got another use case that doesn't involve EF, and I'm trying to merge the two ideas into one reverse-mapping concept. My usage is for ambient View Models in MVVM, merging server API calls into a local VM without replacing all the instances.

Owner

jbogard commented Oct 31, 2014

So the reason this is taking a while to merge is that I've got another use case that doesn't involve EF, and I'm trying to merge the two ideas into one reverse-mapping concept. My usage is for ambient View Models in MVVM, merging server API calls into a local VM without replacing all the instances.

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Oct 31, 2014

Member

So you need to use equality compare when mapping 2 view models, or the same view model but 2 different instances? So you want some kind of convention that will handle this for you instead of manually typing the equality comparison between the two and their children? Like re-syncing view model data? Also does this involve resolving change conflicts, or does the server API call's VM overwrite the values of the local VM?

Member

TylerCarlson1 commented Oct 31, 2014

So you need to use equality compare when mapping 2 view models, or the same view model but 2 different instances? So you want some kind of convention that will handle this for you instead of manually typing the equality comparison between the two and their children? Like re-syncing view model data? Also does this involve resolving change conflicts, or does the server API call's VM overwrite the values of the local VM?

@jbogard

This comment has been minimized.

Show comment Hide comment
@jbogard

jbogard Oct 31, 2014

Owner

Kinda - more like Model comes in from an API call, I want to map into an existing VM instance, adding new children as needed, removing ones that are gone, and updating as necessary. Server overwrites client VMs.

Owner

jbogard commented Oct 31, 2014

Kinda - more like Model comes in from an API call, I want to map into an existing VM instance, adding new children as needed, removing ones that are gone, and updating as necessary. Server overwrites client VMs.

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Oct 31, 2014

Member

So is it a problem with AutoMapper configuration with a VM mapping to a VM of the same type, making the equality comparison follow some convention verses typing it out each one by hand, or just don't have an elegant way, using generics I'm assuming, to wrap the mapping in some kind of class that can "Re-Sync" the data?

Member

TylerCarlson1 commented Oct 31, 2014

So is it a problem with AutoMapper configuration with a VM mapping to a VM of the same type, making the equality comparison follow some convention verses typing it out each one by hand, or just don't have an elegant way, using generics I'm assuming, to wrap the mapping in some kind of class that can "Re-Sync" the data?

@TylerCarlson1

This comment has been minimized.

Show comment Hide comment
@TylerCarlson1

TylerCarlson1 Apr 22, 2015

Member

Moved implementation of base equality comparison to https://github.com/TylerCarlson1/Automapper.Collection.
I still support this being in AutoMapper base, but don't know how long it will be before this will come.

Member

TylerCarlson1 commented Apr 22, 2015

Moved implementation of base equality comparison to https://github.com/TylerCarlson1/Automapper.Collection.
I still support this being in AutoMapper base, but don't know how long it will be before this will come.

@jbogard jbogard removed this from the v.Future milestone Jan 18, 2016

@jbogard jbogard closed this May 19, 2016

@TylerCarlson1 TylerCarlson1 deleted the TylerCarlson1:AddRemoveExistingCollection branch Jun 11, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment