Comments (13)
@furier Hi, thanks for the interest in the library, and good for trying to write the mappers!
Adding support for hot chocolate makes sense. Unfortunately I'm sick now, but I can try something next weekend If I feel better
And yes, the wiki needs more work it's not 100 % completed
from detached-mapper.
I am playing around with implementing a TypeMapperFactory
and TypeMapper
public class OptionalTypeMapperFactory : ITypeMapperFactory
{
public bool CanCreate(Mapper mapper, TypePair typePair)
{
var canCreate = typePair.SourceType.IsComplex() &&
typeof(IOptional).IsAssignableFrom(typePair.SourceType.ClrType) &&
typePair.TargetType.IsPrimitive();
return canCreate;
}
public ITypeMapper Create(Mapper mapper, TypePair typePair) =>
(ITypeMapper) Activator.CreateInstance(typeof (OptionalTypeMapper<,>).MakeGenericType(typePair.SourceType.ClrType, typePair.TargetType.ClrType))!;
}
public class OptionalTypeMapper<TSource, TTarget> : TypeMapper<TSource, TTarget>
{
private readonly PropertyInfo _isEmptyProperty;
private readonly PropertyInfo _valueProperty;
public OptionalTypeMapper()
{
var type = typeof(TSource);
_isEmptyProperty = type.GetProperty("IsEmpty")!;
_valueProperty = type.GetProperty("Value")!;
}
public override TTarget Map(TSource source, TTarget target, IMapContext context)
{
if (source is null || _isEmptyProperty.GetValue(source) is true)
return target;
var value = _valueProperty.GetValue(source);
return (TTarget) Convert.ChangeType(value, typeof(TTarget))!;
}
}
but still getting into trouble...
System.InvalidOperationException: No coercion operator is defined between types 'HotChocolate.Optional`1[System.Nullable`1[System.Guid]]' and 'System.Guid'.
at System.Linq.Expressions.Expression.GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType)
at System.Linq.Expressions.Expression.Convert(Expression expression, Type type, MethodInfo method)
at System.Linq.Expressions.Expression.Convert(Expression expression, Type type)
at Detached.Mappers.EntityFramework.Queries.QueryProvider.CreateFilterExpression[TSource,TTarget](TypePair typePair, ConstantExpression sourceConstant)
at Detached.Mappers.EntityFramework.Queries.QueryProvider.<GetTemplate>b__6_0[TSource,TTarget](QueryCacheKey fn)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Detached.Mappers.EntityFramework.Queries.QueryProvider.GetTemplate[TSource,TTarget]()
at Detached.Mappers.EntityFramework.Queries.QueryProvider.Load[TSource,TTarget](IQueryable`1 queryable, TSource source)
at Detached.Mappers.EntityFramework.EFMapContext.TrackChange[TTarget,TSource,TKey](TTarget entity, TSource source, TKey key, MapperActionType actionType)
at Detached.Mappers.TypeMappers.Entity.Complex.RootEntityTypeMapper`3.Map(TSource source, TTarget target, IMapContext context)
at Detached.Mappers.TypeMappers.TypeMapper`2.Map(Object source, Object target, IMapContext context)
at Detached.Mappers.Mapper.Map(Object source, Type sourceClrType, Object target, Type targetClrType, IMapContext context)
at Detached.Mappers.EntityFramework.EFMapper.Map[TEntity](DbContext dbContext, Object entityOrDTO, MapParameters parameters)
at Detached.Mappers.EntityFramework.EFMapper.<>c__DisplayClass8_0`1.<MapAsync>b__0()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at Gateway.API.Mutations.ProjectMutations.CreateProjects(GatewayDbContext gatewayDbContext, CreateProjectDto[] dtos, CancellationToken cancellationToken) in C:\dev\Connected\src\Gateway\Gateway.API\Mutations\ProjectMutations.cs:line 21
from detached-mapper.
The mapper appears to function properly; however, the issue arises when the library attempts to query for existing entities and tries to extract the key from the DTOs Id property, which is of type Optional. It is unable to coerce this into the appropriate type for the entity's Id property.
from detached-mapper.
Mmm.. in that case, we need to be sure that there is a factory mapper between T and Optional<T> that works in two ways
The mapper tries to convert Id types of it doesn't match
Btw you are welcome to add your changes as a part of the lib
And sorry I can't do more for you at this moment, I feel like s***, but excited that people is playing with this.
from detached-mapper.
First of all, I hope you get well soon! Your health is the most important thing right now, so please take your time to recover.
I appreciate your feedback and the opportunity to contribute to the library. Regarding the addition of this code, I was wondering if you think it would be more appropriate to include this functionality as part of the main library or as a separate NuGet package? This way, users could choose to add support for HotChocolate if needed, without affecting those who don't require it.
Please let me know your thoughts on this when you're feeling better, and there's absolutely no rush. Your well-being comes first.
Take care and get well soon!
from detached-mapper.
@furier thanks for your kind message!
Yup, Detached.Mappers.HotChocolate makes sense, to keep core clean of references.
You are welcome to put it in this repo with your name in the copyright of the project, or in your own repo.
(I can approve the pr or give you more access)
Having the code and tests over there makes easier for me to take a look if there are bugs.
And, there is a Partial Updates page in the wiki, it was meant to describe dtos, Ipatch and Optional fits perfectly there
I can add docs later with the proper credits to you in the wiki and main readme.
from detached-mapper.
@furier Did this work? do you need any extra help?
Also, are you planning to push something about Optional<>? Otherwise I'll create a ticket to implement it later
Thanks
from detached-mapper.
@leonardoporro it currently seem to work, have not picked up any issues with it yet.
however as mentioned before I did convert my DTOs Id
property to no longer be "nullable" with the ?
operator but are still nullable because they are wrapped in the Optional<T>
type. It just has to do with the hotchocolate schema inference, that at least in previous versions it would label types wrapped in optional as not optional without the ?
operator, but seems like they have fixed that in later versions.
I was planning on pushing some changes but right now I have to much going on privately and at work, I am just swamped. I am sorry, id like to contribute... but it will have to wait.
from detached-mapper.
@furier Totally understand you! There is no time for anything. I keep adding things to this lib just because I love it, at a cost of sacrificing other things.
There is no hurry, you may do it whenever you want, no one else asked for this.
You may also push a branch as-is, or send them by email and I will take care of integration and properly credit you.
from detached-mapper.
Added a PR #78
from detached-mapper.
@furier Awesome, thank you!
I found an issue, that is probably also the the cause of your Optional<Nullable<T>>
.
When mapping Optional<T1>
to Optional<T2>
a recursive mapping from T1 to T2 is needed, even if T1 and T2 are of the same type.
NullableTypeMapper is doing that...
For nullable types, there won't be a ton of issues if you let the system cast or convert types, but in your case, Optional<T>
when T is an entity, the mapping will fail, because the mapper copies the values from a DTO (can be the same entity or not) to an already attached entity.
The conversion will fail if T1 and T2 are different, or SaveChangesAsync will fail because the entity state will be detached.
Anyway, awesome contribution! I love it. If you make an update let me know otherwise I will do the fix later.
And I'll probably have to move your code to a new project to remove HotChocolate reference from the core mapper library (as you already mentioned before)
Thanks!
from detached-mapper.
Released https://www.nuget.org/packages/Detached.Mappers.HotChocolate/7.0.1
more work is needed anyway...
from detached-mapper.
credits
https://github.com/leonardoporro/Detached-Mapper/wiki/Partial-Updates
from detached-mapper.
Related Issues (20)
- Complex properties of entity (Owned entities) cannot be used with EFcore mapper HOT 3
- Issue with ComplexType when using EFCore 8.0 HOT 2
- Map keys to entities and vice versa HOT 1
- [NotMapped] Attribute causes a cast error HOT 2
- Use Alternate Keys (Business Keys) to connect disconnected graph as the primary keys are not part of DTO/Disconnected Entity.
- [NotMapped] Attribut
- Exception creating map on static property HOT 1
- Mapping EF child collection of entities with Identity HOT 5
- Upon inserting entities return the newly seeded values for primary keys HOT 3
- lncrease the verbosity of mapping errors HOT 1
- context disposed in MapAsync HOT 3
- Map a collection of DTOs to entities HOT 4
- Invalid cast when mapping List<T> to Collection<T> (or any derived Collection) HOT 4
- Ignore Data Annotation HOT 5
- GraphQL and Detached mapper HOT 7
- Aggregation doesn't seem to work properly HOT 10
- Prerelease .Net 8 HOT 5
- Updating a composite collection removes one entry HOT 5
- MapperException: Can't find a concrete type for abstract type or interface HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from detached-mapper.