Giter VIP home page Giter VIP logo

leonardoporro / detached-mapper Goto Github PK

View Code? Open in Web Editor NEW
126.0 15.0 22.0 3.74 MB

An ORM friendly mapper. Allows saving entire entity graphs. Heavily inspired in GraphDiff and AutoMapper.

License: MIT License

C# 100.00%
entity-framework entity-graph tracked-entities mapping-entities graphdiff entityframework disconected-entities mapper automapper dotnet-core dotnet dotnet-library efcore ef-core mappers ef change-tracker change-detection dtos orm

detached-mapper's People

Contributors

cce32 avatar jeffward01 avatar leonardoporro avatar letsion avatar michaelm223 avatar muellercornelius avatar neman avatar sander-struijk avatar skipper876 avatar stuartleeks avatar traiannemes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

detached-mapper's Issues

Error when working with derived classes

Describe the bug
My EF Core model has entities that use inheritance. Deteached seems to fail when working with these classes.
Whenever it needs to map an object that has children that use inheritance, it tries to instantiate the base class, instead of using one of the derived classes, giving an error if the base class is abstract (or building the incorrect object anyway if it is not).

To Reproduce
Define a EF Core model that uses inheritance, like for example:

modelBuilder.Entity<TaskTriggerBase>()
                .HasDiscriminator(x => x.TriggerType)
                .HasValue<TaskTriggerCron>(TaskTriggerType.CronSchedule)
                .HasValue<TaskTriggerReactiveQlik>(TaskTriggerType.AfterQlikTask)
                .HasValue<TaskTriggerReactiveEpr>(TaskTriggerType.AfterEpReporterTask);
modelBuilder.Entity<TaskTriggerCron>();
modelBuilder.Entity<TaskTriggerReactiveEpr>();
modelBuilder.Entity<TaskTriggerReactiveQlik>();

and have an entity like this:

public class Entity{
  [Composition]
  public IEnumerable<TaskTriggerBase> Triggers {get; set;} //this collection can contain instances of any subclass of TaskTriggerBase
  //... other properties...
}

then, try to map it with Deteached. You will get an error like this:

System.InvalidOperationException: 'Can't construct TaskTriggerBase. It does not have a parameterless constructor or a concrete type specified.'

Expected behavior
Deteached should check the actual instance type of the entities and instantiate the correct subclass instead of the base class.

Additional context
Using EF Core 6 on .NET 6, latest version of Deteached available on NuGet.

Ignore Data Annotation

Is your feature request related to a problem? Please describe.
The following situation:
What if you don't want to save things in the DB, but still want to map them?
This does not work with the solution to use [NotMapped] as Ignore attribute.

Describe the solution you'd like
Use a custom attribute such as [Ignore].

Describe alternatives you've considered
Removed [NotMapped] attribute and implemented the NotMapped feature in EF Core via Fluent API.

Example:

modelbuilder.Entity<...>().Ignore(e => e.[Property)

Why reloading the entity again after updating?

First of all great job. I'm currently a user of GraphDiff and was planning to move to EF.Core once it's more mature like EF6.

The code looks much more cleaner and easy to understand.

I have a couple of questions when Updating an entity.

  1. Why are you reloading the root after persisting? Wouldn't EF.Core set the id's automatically?

  2. Does Detached support 3 and more levels of nested tables?

  3. I have a large entity spread among 20 tables and because the entity loaded piece by piece (depending on the user if he wants to load some particular details). So, on updating the entity, currently in GraphDiff I do:

`
//Root
var updatedEntity = ((DbContext)dataContext).UpdateGraph (entity, map => map.AssociatedEntity(x => x.Type)); //And all other mappings here

//Detach it for now...
var state = dataContext.GetEntry(abo).State;
dataContext.GetEntry(abo).State = EntityState.Detached;

//Save some child table which would have been loaded separately and attached to the entity 
if (entity.Children?.Any() ?? true)
{
    //This is a workaround because GraphDiff needs the id's
    entity.Children.ToList()
        .ForEach(x =>
        {
            x.EntityId = x.Id == 0 ? 0 : entity.Id;
            x.ForeignId = x.Foreign.Id;
         });

    //Save the children
    var temp = ((DbContext)dataContext).UpdateGraph<MyEntity>
        (entity, //Any mappings here...);

    //Attach updated children to the entity we just saved above
    foreach (var child in temp.Children)
    {
        updatedEntity.Children.Add(child);
    }

    //Detach the changed entity as this is just temporary
    dataContext.GetEntry(temp).State = EntityState.Detached;
}

//Do the same for other child tables

//Re-attach the updated entity
dataContext.GetEntry(updatedEntity).State = state;
return updatedEntity;`

Would this workflow still be possible using Detached and maybe even simplified to improve performance because currently the whole save method with GraphDiff takes a few seconds to complete

Unable to resolve dependencies.

First of all congratulations for your initiative! I went into crisis when I realized that GraphDiff does not work with version EntityFrameworkCore. I hope that your project goes ahead. It would be very interesting!

But here's the problem:
"Unable to resolve dependencies. 'Microsoft.EntityFrameworkCore 1.0.1' is not compatible with 'EntityFrameworkCore.Detached 1.0.0-alpha8 constraint: Microsoft.EntityFrameworkCore (>= 1.1.0-alpha1-22131)".

Create mapping profiles

Hi, thanks for great library!

I wanted to ask because I don't see any example of that - is this library supports something similar to AutoMapper's CreateMap?
By that I mean any simple interface that allows to create mapping profiles.

Best regards!

ArgumentException: Static property requires null instance, non-static property requires non-null instance. (Parameter 'expression')

Hello!
I'm trying to use Detached-Mapper for the first time. I've installed the NuGet package and registered the dependencies. I was hit by the following error:

ArgumentException: Static property requires null instance, non-static property requires non-null instance. (Parameter 'expression')
System.Linq.Expressions.Expression.Property(Expression expression, PropertyInfo property)

With stack trace:

System.Linq.Expressions.Expression.Property(Expression expression, PropertyInfo property)
Detached.Mappers.TypeOptions.Types.Class.ClassOptionsFactory.Create(MapperOptions options, Type type)
Detached.Mappers.MapperOptions+<>c__DisplayClass27_0.b__0(Type keyType)
System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>.GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
Detached.Mappers.MapperOptions.GetTypeOptions(Type type)
Detached.Mappers.TypeMaps.TypeMapFactory.IsBackReference(MapperOptions options, TypeMap typeMap, IMemberOptions memberOptions, out BackReferenceMap backReferenceMap)
Detached.Mappers.TypeMaps.TypeMapFactory.Create(Mapper mapper, MapperOptions options, TypeMap parentMap, Type sourceType, Type targetType, bool isComposition)
Detached.Mappers.Mapper.GetTypeMap(Type sourceType, Type targetType)
Detached.Mappers.Mapper.b__6_0<TSource, TTarget>(ICacheEntry entry)
Microsoft.Extensions.Caching.Memory.CacheExtensions.GetOrCreate(IMemoryCache cache, object key, Func<ICacheEntry, TItem> factory)
Detached.Mappers.Mapper.Map<TSource, TTarget>(TSource source, TTarget target, IMapperContext context)
lambda_method206(Closure , object , object , IMapperContext )
Detached.Mappers.Mapper.Map(object source, Type sourceType, object target, Type targetType, IMapperContext context)
Detached.Mappers.EntityFramework.DbContextExtensions.Map(DbContext dbContext, object entityOrDTO, MapperParameters parameters)
FirmBasket.Server.Controllers.SyncController.Slovakia() in SyncController.cs
context.Map(changedOrganization);

My code:

var response = await client.GetAsync("https://datahub.ekosystem.slovensko.digital/api/data/rpo/organizations/sync");
response.EnsureSuccessStatusCode();

var changedOrganizations = await response.Content.ReadFromJsonAsync<Organization[]>();
if(changedOrganizations != null)
{
    foreach (var changedOrganization in changedOrganizations)
    {
         context.Map<Organization>(changedOrganization);
    }
}

The Organization is a database entity - definition on pastebin.
image

Any tips on what can be causing the exception?

I need some help with mapping related entities

For now my test action in abstract crud controller be like:

        [EnableQuery]
        [HttpPatch("/odata/[controller]({id:int})")]
        public virtual async Task<ActionResult<TEntity>> Patch(int id, [FromBody]TEntity delta, CancellationToken ctx)
        {
            var entity = PatchTypeFactory.Create<TEntity>();
            var type = typeof(TEntity);
            
            foreach (var property in type.GetProperties())
            {
                property.SetValue(entity, property.GetValue(delta));
            }
            entity.Id = id;
            await _db.MapAsync<TEntity>(entity);
            await _db.SaveChangesAsync(ctx);
            return Updated(entity);
        }

and entities are:

    public class User : IHasId
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual int Age { get; set; }
        public virtual int? RoleId { get; set; }
        [Aggregation]
        public virtual Role? Role { get; set; }
    }

    public class Role : IHasId
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        [Composition]
        public virtual List<User>? Users { get; set; }
        [Composition]
        public virtual List<Permission>? Permissions { get; set; }
    }

    public class Permission : IHasId
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        [Composition]
        public virtual List<Role>? Roles { get; set; }
    }

and when I send this request:

PATCH https://localhost:5001/odata/users(8)
Accept: application/json
OData-Version: 4.0
Content-Type: application/json;odata.metadata=full;odata.streaming=true;IEEE754Compatible=false;charset=utf-8

{
  "RoleId": 8,
  "Role": {
    "Id": 8,
    "Name": "RENAMED Role 8",
    "Permissions": [
      {
        "Id": 14,
        "Name": "RENAMED Permission 14"
      },
      {
        "Id": 15,
        "Name": "NEW Permission 15"
      }
    ]
  }
}

(and state of records in db: user exists without any role, role exists without any permissions, first permission exist and second permission not)

I'm expecting, that user # 8 be related to role # 8, role # 8 be related to existed permission # 14 and permission # 15 will be created and related to role # 8.

But for now only user # 8 related to role # 8...

Postgresql integration with NpgsqlTsVector field type

Describe the bug
I am using PostgresSQL 14 database with the field for Full Text Search.
You can find detail here : https://www.npgsql.org/efcore/mapping/full-text-search.html?tabs=pg12%2Cv5
When i use context.MapAsync() function i've got an error and the application fail.

To Reproduce
Steps to reproduce the behavior:

  1. create an entity with NpgsqlTsVector field
  2. create migration and database
  3. create a new reference of the entity
  4. use context.MapAsync() function
  5. You can see the error message is : System.ArgumentException: Incorrect number of arguments supplied for call to method 'WordEntryPos get_Item(Int32)' (Parameter 'property')

Expected behavior
Could you correct the bug or tell me a walk around to be able to use this field with Map function.

Two levels of composition doesn't work

Describe the bug
Two levels of composition doesn't work with EF Core

To Reproduce
Invoice -> Invoice Line Item -> Invoice Item details

class Invoice
{
    [Composition] 
    List<InvoiceLineItem> InvoiceLineItems { get; set; }
}

class InvoiceLineItem
{
    [Composition]

    List<InvoiceItemDetails> InvoiceItemDetails { get; set; }
}

class InvoiceItemDetails
{
   
}

Expected behavior
MapAsync to track down to second level, it only tracks first with EF Core and all InvoiceItemDetails are tracked as Added.

context disposed in MapAsync

Call to MapAsync gives me a context disposed exception 'System.ObjectDisposedException: 'Cannot access a disposed context instance'.

at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.Set[TEntity]()
   at Detached.Mappers.EntityFramework.EFMapContext.TrackChange[TTarget,TSource,TKey](TTarget entity, TSource source, TKey key, MapperActionType actionType) in D:\Nextcloud\Programacion\MisCodigos\ZsaLobApiMVC\Detached-Mapper-main\src\Detached.Mappers.EntityFramework\EFMapContext.cs:line 31
   at Detached.Mappers.TypeMappers.Entity.Complex.RootEntityTypeMapper`3.Map(TSource source, TTarget target, IMapContext context) in D:\Nextcloud\Programacion\MisCodigos\ZsaLobApiMVC\Detached-Mapper-main\src\Detached.Mappers\TypeMappers\Entity\Complex\RootEntityTypeMapper.cs:line 36
   at Detached.Mappers.TypeMappers.TypeMapper`2.Map(Object source, Object target, IMapContext context) in D:\Nextcloud\Programacion\MisCodigos\ZsaLobApiMVC\Detached-Mapper-main\src\Detached.Mappers\TypeMappers\TypeMapper.cs:line 11
   at Detached.Mappers.Mapper.Map(Object source, Type sourceClrType, Object target, Type targetClrType, IMapContext context) in D:\Nextcloud\Programacion\MisCodigos\ZsaLobApiMVC\Detached-Mapper-main\src\Detached.Mappers\Mapper.cs:line 46
   at Detached.Mappers.EntityFramework.EFMapper.Map[TEntity](DbContext dbContext, Object entityOrDTO, MapParameters parameters) in D:\Nextcloud\Programacion\MisCodigos\ZsaLobApiMVC\Detached-Mapper-main\src\Detached.Mappers.EntityFramework\EFMapper.cs:line 82
   at Detached.Mappers.EntityFramework.EFMapper.<>c__DisplayClass8_0`1.<MapAsync>b__0() in D:\Nextcloud\Programacion\MisCodigos\ZsaLobApiMVC\Detached-Mapper-main\src\Detached.Mappers.EntityFramework\EFMapper.cs:line 67
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
builder.Services.AddDbContext<ApplicationDbContext>(options => 
    options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))
    .UseDetached());
    public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

        public DbSet<Contacto> Contactos { get; set; }
        public DbSet<ContactoTipo> ContactoTipos { get; set; }

    }
    [Route("api/[controller]")]
    [ApiController]
    public class ContactosController : ControllerBase
    {
        ApplicationDbContext _context; 

        public ContactosController(ApplicationDbContext context)
        {
            _context = context;
        }

        // PUT api/<ContactosController>/5
        [HttpPut("{id}")]
        public async void Put(int id, [FromBody] AddUpdateContactoDTO value)
        {
                var entity = await _context.MapAsync<Contacto>(value);
                await _context.SaveChangesAsync();
        }
    }
}

I'm using .Net Core 7 , And Pomelo MySql adapter for context.
Any idea what could be wrong ?

Unable to find package

Hi,
I decided to give Detached a try, but when trying to install it in my current project I get

PM> Install-Package Detached.Mappers.EntityFramework
Install-Package : Unable to find package 'Detached.Mappers.EntityFramework'
At line:1 char:1
+ Install-Package Detached.Mappers.EntityFramework
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
 
Time Elapsed: 00:00:03.7855917

It seems it's not present on the Nuget package Manager. Any workaround?

Having multiple navigation properties to the same table results in incorrect EntityState for second property's children

There seems to be an issue for the following graph:

class A
{
public int Id{get;set;}
[Owned]
public B B1{get;set;}
[Owned]
public B B2{get;set;}
}

class B
{
public int Id{get;set;}
[Owned]
public ICollection C {get;set} <= these will be set to Added on B2
}

class C
{
public int Id {get;set;}
string Prop1{get;set;}
}
When doing dbContext.Set.UpdateAsync(myAObject) , it is flagging the C elements in B1 as Added even though their Id properties are set.

Is [Entity] attribute required?

I'm migrating my models to EF Core and Detached. Do I still need the [Entity] attribute on my model classes or is it handled by EF Core?

Configure associations for each map operation

I have quite a large project which I just migrated to NET7. Unfortunately the DAL project is sill using EF6 (6.4.4) because it uses GraphDiff for updates (and inserts). A simple example might be:

    var updated = ((DbContext)dataContext).UpdateGraph<Customer>
        (entity,
            map => map.AssociatedEntity(x => x.CustomerType)
                        .AssociatedEntity(x => x.Title)
                        .AssociatedEntity(x => x.Gender)
                        .OwnedEntity(x => x.Address, with => with
                            .AssociatedEntity(t => t.Title)
                            .AssociatedEntity(p => p.PostCode))
                        .OwnedEntity(x => x.BillingAddress, with => with
                            .AssociatedEntity(t => t.Title)
                            .AssociatedEntity(p => p.PostCode))
                        .OwnedEntity(x => x.ShippingAddress, with => with
                            .AssociatedEntity(t => t.Title)
                            .AssociatedEntity(p => p.PostCode))
                        .OwnedCollection(x => x.BankCodes, with => with
                            .AssociatedEntity(t => t.AccountHolder))
                        .OwnedCollection(x => x.Creditcards, with => with
                            .AssociatedEntity(t => t.Title)
                            .AssociatedEntity(b => b.BankCode)
                            .AssociatedEntity(c => c.Creditcard))

This is still working fine but it is time to upgrade to EFCore. The entity that is passed to the update method has been already mapped from DTO to a model at an earlier stage, so mapping from DTO to models is not required.

One problem that I see with using the Aggregation and Composition attributes at the property level is that some object graphs get way too complex. For example in the above, PostCode is associated with Address. However PostCode has further links to additional classes such as State, County and Country. When saving the customer these additional classes do not need to be loaded and updated. So that it why they are not included above.

Is it possible to add extensions to Detached to mimic the above GraphDiff methods?

Problem with a many-to-many relation

Describe the bug
I have the repro here: https://dotnetfiddle.net/dD69D8 I'm trying to update an entity that can have a few documents. In my case its done in a web frontend (not that it matters, but to give a bit of context) where you can use a dropdown to select one or more existing documents. This repro is for scenario a) Adding existing documents to an existing entity. There is a scenario b (having one linked document and adding a second), but maybe I'm doing this wrong so I want to focus on this one.

To Reproduce
See this repro: https://dotnetfiddle.net/dD69D8

Expected behavior
End state should be that Parent has two linked documents, pointing to the existing documents made in line 20/21.

Stack
Does not really matter I think. Just latest EF core with latest version of this project.

Additional context
Add any other context about the problem here.

Mapper doesn't work when using concurrency token as Timestamp/Rowversion

Usually the token is mapped to a byte[] and the error looks like the folowing. If there is a workaround, please share it.

Message:
System.InvalidOperationException : Can't construct byte[]. It does not have a parameterless constructor or a concrete type specified.
Stack Trace:
ClassTypeOptions.Construct(Expression context)
ListMapperFactory.Create(TypeMap typeMap)
MapperFactory.CreateMapper(TypeMap typeMap)
MapperFactory.CreateMemberMappers(TypeMap typeMap, Func2 filter) EntityListMapperFactory.Create(TypeMap typeMap) MapperFactory.CreateMapper(TypeMap typeMap) MapperFactory.CreateMemberMappers(TypeMap typeMap, Func2 filter)
EntityListMapperFactory.Create(TypeMap typeMap)
MapperFactory.CreateMapper(TypeMap typeMap)
MapperFactory.CreateMemberMappers(TypeMap typeMap, Func2 filter) EntityRootMapperFactory.Create(TypeMap typeMap) Mapper.<Map>b__6_0[TSource,TTarget](ICacheEntry entry) CacheExtensions.GetOrCreate[TItem](IMemoryCache cache, Object key, Func2 factory)
Mapper.Map[TSource,TTarget](TSource source, TTarget target, IMapperContext context)
lambda_method(Closure , Object , Object , IMapperContext )
Mapper.Map(Object source, Type sourceType, Object target, Type targetType, IMapperContext context)
DbContextExtensions.Map[TEntity](DbContext dbContext, Object entityOrDTO, MapperParameters parameters)

Allow mapping of composition enumerables with a getter only

I usually define collections in my entities with a getter only like this:

public class GroupReservation
{
    [Key]
    public int Id { get; set; }
    public string? Reference { get; set; }
    [Composition]
    public List<Reservation> Reservations { get; } = new List<Reservation>();
}

However, when Mapping a DTO to such an entity, the collections will remain empty. To fix this one, the collection on the entity requires a setter:

public class GroupReservation
{
    [Key]
    public int Id { get; set; }
    public string? Reference { get; set; }
    [Composition]
    public List<Reservation> Reservations { get; set; }
}

I would therefore like to ask if it would be possible to allow collections with a getter only to be mapped.

Preserving unloaded related data

Describe the bug
Sorry, here I am again.
Repro here: https://dotnetfiddle.net/wDbM8i
Parent is being saved with some stuff changed but with
The parent has a one-to-many to details but when saving the parent without details loaded I get an error:

The association between entity types 'Parent' and 'Detail' has been severed, but the relationship is either marked as required or is implicitly required because the foreign key is not nullable. If the dependent/child entity should be deleted when a required relationship is severed, configure the relationship to use cascade deletes. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the key values.
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at Program.Main()
Command terminated by signal 6

Expected behavior
Expectation is to save everything, and leave all the associated details as is.

Additional context
I think my fiddle is using 5.0.21 but I ran into this with 5.0.22. It might be that Detached-PatchTypes is the solution to this, but I'm using newtonsoft json for serializing requests so I couldn't get that to work in my project.

Configure array of primitives as primitive by default (Error with RowVersion column)

Have an entity like
public class Timesheet
{
public int TimesheetId { get; set; }

public DateTime StartDate { get; set; }

public DateTime EndDate { get; set; }

[Timestamp]
public byte[] RowVersion { get; set; }

}

Update like
await context.MapAsync();
context.SaveChanges();

You will get an error:
System.InvalidOperationException: 'An error was generated for warning 'Microsoft.EntityFrameworkCore.Query.InvalidIncludePathError': Unable to find navigation 'RowVersion' specified in string based include path 'RowVersion'. This exception can be suppressed or logged by passing event ID 'CoreEventId.InvalidIncludePathError' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.'

This started to happen with versions higher than 6.0.6

Here is sample code
ConsoleApp2.zip

Mutiple many-to-many constraint bug?

When a related item is added (Aggregation annotation) the same item gets added to another many-to-many collection.
If I add a user as a member, then after saving the context, the same relation is added to another many-to-many relation:

image

I have the following classes:

User
[Aggregation]
public IList MemberOfGroups { get; set; }
[Aggregation]
public IList MemberOfGroupsToSync { get; set; }
[Aggregation]
public IList MembertOfGroupsRequests { get; set; }
[Aggregation]
public IList OwnerOfGroups { get; set; }
[Aggregation]
public IList OwnerOfGroupsToSync { get; set; }
[Aggregation]
public IList OwnerOfGroupsRequests { get; set; }

Group:
[Aggregation]
public IList Members { get; set; }
[Aggregation]
public IList MembersToSync { get; set; }
[Aggregation]
public IList MembersRequests { get; set; }
[Aggregation]
public IList Owners { get; set; }
[Aggregation]
public IList OwnersToSync { get; set; }
[Aggregation]
public IList OwnersRequests { get; set; }

DBContext:
modelBuilder.Entity()
.HasMany(t => t.Owners)
.WithMany(o => o.OwnerOfGroups)
.UsingEntity(j => j.ToTable("Owners"));

        modelBuilder.Entity<GroupItem>()
                        .HasMany(t => t.OwnersRequests)
                        .WithMany(o => o.OwnerOfGroupsRequests)
                        .UsingEntity(j => j.ToTable("OwnerRequests"));

        modelBuilder.Entity<GroupItem>()
                        .HasMany(t => t.OwnersToSync)
                        .WithMany(o => o.OwnerOfGroupsToSync)
                        .UsingEntity(j => j.ToTable("OwnersSync"));

        modelBuilder.Entity<GroupItem>()
                    .HasMany(t => t.Members)
                    .WithMany(o => o.MemberOfGroups)
                    .UsingEntity(j => j.ToTable("Members"));

        modelBuilder.Entity<GroupItem>()
                    .HasMany(t => t.MembersRequests)
                    .WithMany(o => o.MembertOfGroupsRequests)
                    .UsingEntity(j => j.ToTable("MemberRequests"));

        modelBuilder.Entity<GroupItem>()
                    .HasMany(t => t.MembersToSync)
                    .WithMany(o => o.MemberOfGroupsToSync)
                    .UsingEntity(j => j.ToTable("MembersSync"));

Extra screenshot:
image

Multiple Associated Attribute properties in graph does not load correctly

Given the following example

class One {
public long Id {get;set;}
[Associated]
public Two Two {get;set;}
}

class Two {
public long Id {get;set;}
[Associated] => changing this to [Owned] will load correctly
public Three Three {get;set;}
}

public class Three{
 public long Id {get;set;}
}

detachedContext.Set<One>().LoadAsync(some_id); => will not load One.Two.Three

System.InvalidOperationException when Using Table Splitting

Hi Leonardo,

I'm getting this:
System.InvalidOperationException: 'The property 'LargeBlob.Id' is part of a key and so cannot be modified or marked as modified. To change the principal of an existing entity with an identifying foreign key, first delete the dependent and invoke 'SaveChanges', and then associate the dependent with the new principal.'

I was trying this sample here: https://entityframeworkcore.com/knowledge-base/49470417/ef-core-2-0---2-1---------------------

Do you have an idea if this is a bug or not? is there a workaround for it?

Cheers,
Rico

Having trouble understanding why a property update doesn't work

I have the following example:

class A {
   public long BId {get;set;}
   public long CId {get;set;}
   public string Property {get;set;}

  [JsonIgnore]
  public B BProperty {get;set;}
  [JsonIgnore]
  public C CProperty {get;set;}
}
class B {
   [Owned]
   public ICollection<A> ACollection {get;set;}
}

class C {
   [Owned]
   public ICollection<A> ACollection {get; set;}
}

after calling await detached.Set<C>().UpdateAsync(cObject);

the A.Property get's updated but A.BId doesn't update.

What i'm doing wrong?

Thanks

DetachedContext fails to get service IDetachedContextServices

I have added services.AddTransient(typeof(IDetachedContext<>), typeof(DetachedContext<>));
in my Setup class but when the DetachedContext is created the code in DetachedContext fails to get service. _detachedServices = _serviceProvider.GetService();

What am i missing ?

EntityFrameworkCore.Query.NavigationBaseIncludeIgnored Error

I am using your package for long time. Recently, I update all the packages (yours and EntityFramework as well) and I cannot use _dbContext.MapAsync() function.

I have the following error message.

System.InvalidOperationException: An error was generated for warning 'Microsoft.EntityFrameworkCore.Query.NavigationBaseIncludeIgnored': The navigation 'LigneFacture.Facture' was ignored from 'Include' in the query since the fix-up will automatically populate it. If any further navigations are specified in 'Include' afterwards then they will be ignored. Walking back include tree is not allowed.

I am lost, i don't know how to solve it.

Could you tell me how i can solve the problem ?

How to map multi-level profiles?

If I have the following models:

public class Customer() {
    public int Id { get; set; }
    public virtual ICollection<CustomerCreditCard> CreditCards { get; set; }
}

public class CustomerCreditCard() {
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public int CreditCardId { get; set; }
    public virtual CreditCard CreditCard { get; set; }
}

public class CreditCard() {
    public int Id { get; set; }
}

Is this the correct way to create the mapping profiles:

cfg.Type<Customer>()
    .Member(x => x.CreditCards).Composition();

cfg.Type<CustomerCreditCard>()
    .Member(x => x.CreditCard).Association();

Or is it just a single compound mapping for the Customer entity?

Ideas and Suggestions

I'm happy I found this project as I am a user of graphdiff. How does it compare? Is the same featureset supported?

How to map a child item when creating a parent item? (not a bug more a question)

Is it even possible like this?

TestDbContext db = await TestDbContext.CreateAsync();

Role role = new Role() { Name = "Test" };
db.Roles.Add(role);
await db.SaveChangesAsync();

// Create user and assign existing role
User user = new() { Name = "Example" };
user.Roles.Add(role);

await db.MapAsync<User>(user);

await db.SaveChangesAsync();

Issue with netcore 2.0

Could you please update your great solution to netcore 2.0?
Because current version has issues with compatible.
Thank you!

Invalid cast when mapping List<T> to Collection<T> (or any derived Collection)

Describe the bug
When using Collection (or in my case ObservableCollection) in POCOs that have to be mapped, a Invalid cast exception occurs.

To Reproduce
Steps to reproduce the behavior:

Mapper mapper = new Mapper();
List<int> ints = new List<int> { 1, 2, 3, 4, 5 };
Collection<string> result = mapper.Map<List<int>, Collection<string>>(ints);

Expected behavior
The List<T> should be correctly mapped to Collection<T>.
The constraints of CollectionTypeMapper would imply that as well:

where TSource : class, IEnumerable<TSourceItem>
where TTarget : class, ICollection<TTargetItem>

Solution
The problem is that CollectionTypeMapper.Map() uses List<T> internally to build the target list and tries to cast it to the target type. List<T> cannot be cast to Collection<T>.
It would be better to use Activator.CreateInstance<TTarget>() so mapping every type of collection is supported.

I'll create a pull request in a few minutes.

Create mapper for ValueConverter

Hi

Premise:

I have a situation where I'm using a ValueConverter to map a property with a complex type to a simple string in the database.

This is how my entity looks:

public class MyEntity {
  public List<Foo> Foos {get; set;}

  //other fields
}

in my EF Core configuration, I specify that that particular property uses a converter:

modelBuilder.Entity<MyEntity >()
    .Property(x => x.Foos)
    .HasConversion<FooListConverter>();

The converter looks like this:

public class FooListConverter: ValueConverter<List<Foo>, string>{
  //conversion implementation
}

so, as you can see, it converts the List to a simple string, so it can be stored directly in the database.

The problem:

I'm trying to use Detached-Mapper to update an entity of type MyEntity, like this:

dbContext.Map<MyEntity>(entityDto);

however, this call is throwing the following exception:

An error was generated for warning 'Microsoft.EntityFrameworkCore.Query.InvalidIncludePathError': Unable to find navigation 'Foos' specified in string based include path 'MyEntity.Foos'. This exception can be suppressed or logged by passing event ID 'CoreEventId.InvalidIncludePathError' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.

I'm a bit ignorant on this subject, so I may be completely wrong here, but I think Detached-Mapper is trying to treat the Foos property as a navigation property (a relationship). However, this is not a relationship, it is a simple field that is mapped directly to a DB column by converting it to a string (thanks to the ValueConverter).

I tried to mark the Foos property with the [Composition] attribute, and in that case I get past that error, however the problem is that now I get the same error for each property with a complex type inside the Foo object, because Detached is trying to go down and map everything inside the object (since it is marked as Composition). I haven't tested if marking every complex type inside Foo and its children as [Composition] fixes the problem, because some types inside it are from an assembly that doesn't reference Detached, so I cannot apply the attribute to their properties. However, even if it works it would just be a workaround and probably not the correct approach.

I think the "proper" solution would be for Detach to not treat properties that have a custom converter as navigation properties, if it is possible to do so automatically.
Alternatively, maybe there is a way that I don't know to mark a property so it is treated as a "simple" (directly mappable to db) value and ignored? Can anyone help me out?

Thanks in advance for any support you can give me, and for your work on the library, it's awesome.

lncrease the verbosity of mapping errors

Discussed in #72

Originally posted by heyadamhey March 10, 2023
When I'm mapping an object graph, I get the following exception

System.NullReferenceException: 'Object reference not set to an instance of an object.'

Stack Trace:

'_context.Map<Domain.Casino>(casino)' threw an exception of type 'System.NullReferenceException'
    Data: {System.Collections.ListDictionaryInternal}
    HResult: -2147467261
    HelpLink: null
    InnerException: null
    Message: "Object reference not set to an instance of an object."
    Source: "Detached.Mappers"
    StackTrace: "   at Detached.Mappers.NotMappedParentAnnotationHandlerExtensions.NotMapped(ITypeMember member, Boolean value)\r\n   at Detached.Mappers.Annotations.NotMappedAnnotationHandler.Apply(NotMappedAttribute annotation, MapperOptions mapperOptions, ClassType typeOptions, ClassTypeMember memberOptions)\r\n   at Detached.Mappers.Annotations.AnnotationHandler`1.Apply(Attribute annotation, MapperOptions mapperOptions, ClassType typeOptions, ClassTypeMember memberOptions)\r\n   at Detached.Mappers.Types.Class.ClassTypeFactory.Create(MapperOptions options, Type type)\r\n   at Detached.Mappers.MapperOptions.<>c__DisplayClass34_0.<GetType>b__0(Type keyType)\r\n   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)\r\n   at Detached.Mappers.MapperOptions.GetType(Type type)\r\n   at Detached.Mappers.TypeMappers.ExpressionBuilder.BuildMapSingleMemberExpression(TypePairMember memberPair, Expression sourceExpr, Expression targetExpr, Expression contextExpr)\r\n   at Det
ached.Mappers.TypeMappers.ExpressionBuilder.BuildMapAllMembersExpression(TypePair typePair, Expression sourceExpr, Expression targetExpr, Expression contextExpr, Func`3 isIncluded)\r\n   at Detached.Mappers.TypeMappers.ExpressionBuilder.BuildMapMembersExpression(TypePair typePair, Func`3 isIncluded)\r\n   at Detached.Mappers.TypeMappers.Entity.Complex.EntityTypeMapperFactory.Create(Mapper mapper, TypePair typePair)\r\n   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)\r\n   at Detached.Mappers.Mapper.GetTypeMapper(TypePair typePair)\r\n   at Detached.Mappers.Mapper.Map(Object source, Type sourceClrType, Object target, Type targetClrType, IMapContext context)\r\n   at Detached.Mappers.EntityFramework.EFMapper.Map[TEntity](DbContext dbContext, Object entityOrDTO, MapParameters parameters)\r\n   at Detached.Mappers.EntityFramework.MappingDbContextExtensions.Map[TEntity](DbContext dbContext, Object entityOrDTO, MapParameters mapParams)"
    TargetSite: {Void NotMapped(Detached.Mappers.Types.ITypeMember, Boolean)}

for context, in _context.Map<Domain.Casino>(casino) casino is a Domain.Casino, so the type is the same and therefore all properties will be a 1:1 match.
The Exception Details window doesn't provide any insight into what is causing the mapping to fail.

I experienced this on a simpler object because a nullable DateTime property was null. When I ensured the property had a value, the mapping succeeded. When I try mapping an object with a lot of properties, collections etc I get the exception, but it would be great to find a simple way to debug the breakdown in the mapping. Maybe it's trying to map a nullable to a non-nullable property, which is easy enough to fix but knowing which property to address would be a huge help

Thanks
Adam

Multiple delete

"Sending a list of Ids (long) to DeleteAsync throws the following exception "Object must implement IConvertible."
Casting the list to an object array I get the following "One or more errors occurred. (Key values count mismatch, expected Id)"

Readme shows wrong example

The example in the readme seems wrong after I upgraded to 6.2.2 (came from 6.0.6)

This:

services.AddDbContext<MainDbContext>(cfg =>
    {
        ...
        cfg.UseDetached(options => {
            options.Configure<Invoice>().Member(i => i.Rows).Composition();
        });
    });

Works only as I change it into this:

services.AddDbContext<MainDbContext>(cfg =>
    {
        ...
        cfg.UseDetached(options => {
            options.Type<Invoice>().Member(i => i.Rows).IsComposition(true);
        });
    });

If I'm reading that correct?

Upon inserting entities return the newly seeded values for primary keys

Describe the solution you'd like
When calling EF like context.Add(entity) or context.Update(entity) for the all the records that EF inserts it returns back the seeded value for primary key. EF by default follows each INSERT with SELECT SCOPE_IDENTITY() when auto-generated Ids are used.

It would be nice to have similar functionality with context.MapAsync(entity) follow by context.SaveChanges()
Describe alternatives you've considered
Right now I call another end point (if it's an API) to get the newly inserted record

Additional context
Add any other context or screenshots about the feature request here.

Mapping EF child collection of entities with Identity

I am having root entity in EF that has a few children. Some children have explicit keys and they mapped/populated as expected.
One child has Identity primary key, and it is not mapped and cause errors:
The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded.
My code is just
var entity = await dataContext.MapAsync<RootEntity>(dataModel);
In dataModel I have fields populated

"ChildrenWithIdentity": [
{
"Id": 0,
"ItineraryId": 73551,
"PopulatedProperty": "EzgybP6Y4qApGZYyA0Hqvw==",
}
]
but in mapped entity key is also 0 ,but properties are not copied
"ChildrenWithIdentity": [
{
"Id": 0,
"ItineraryId": 0,
//Properties are null
}
]

Do you support child entities with GeneratedOption.Identity?
If yes, can you suggest what else can be wrong with my ChildrenWithIdentity ?
Is any tracing can be enabled that explain why mapping for this child doesn't work ?

Tor now, I've excluded ChildrenWithIdentity property by calling entity.ChildrenWithIdentity .Clear(),and process the children manually. Can you suggest other way to exclude children properties from map?

Example of my schema
public class RootEntity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ItineraryId { get; set; }

    //Navigation Properties
    public List<WorkingChild> WorkingChildren{ get; set; }

    public List<ChildWithIdentity> ChildrenWithIdentity{ get; set; }

}
For children that have known keys MapAsync works ok,
But for table with autogenrated ID it creates object with no properties

public class WorkingChild
{
[Key, Required, DatabaseGenerated(DatabaseGeneratedOption.None)]//No IDENTITY
public int ComponentId { get; set; }
public int ItineraryId { get; set; }
//other properties
}
public class ChildWithIdentity
{

  [Key, Required,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id{ get; set; }

public int ItineraryId { get; set; }
//other properties
}

No factory for Optional<Guid?> -> Guid

Hi

I am trying to map HotChocolate input types to entities and get this error, and could not find anything in the wiki on how to do this.

Here are example classes for DTO and Entity

public partial class CreateProjectDto
{
    public Optional<Guid?> Id { get; set; }
    public string Name { get; set; }
}

public class Project 
{
    public Guid Id { get; set; }
    public string Name { get; set; };
}

Running the following code generates an exception

var project = await dbContext.MapAsync<Project>(dto);

Exception

Detached.Mappers.Exceptions.MapperException: No factory for Optional<Guid?> -> Guid
   at Detached.Mappers.Mapper.<>c__DisplayClass9_0.<GetTypeMapper>b__0(TypePairKey key)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Detached.Mappers.Mapper.GetTypeMapper(TypePair typePair)
   at Detached.Mappers.TypeMappers.ExpressionBuilder.BuildGetKeyExpressions(TypePair typePair, LambdaExpression& getSourceKeyExpr, LambdaExpression& getTargetKeyExpr, Type& keyType)
   at Detached.Mappers.TypeMappers.Entity.Complex.EntityTypeMapperFactory.Create(Mapper mapper, TypePair typePair)
   at Detached.Mappers.Mapper.<>c__DisplayClass9_0.<GetTypeMapper>b__0(TypePairKey key)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Detached.Mappers.Mapper.GetTypeMapper(TypePair typePair)
   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

Map a collection of DTOs to entities

Id like to map a collection of DTOs to entities like this

var entities = await dbContext.MapManyAsync<Entity>(dtos);

Currently I have to do the following? which has some overhead with spawning a task for each DTO being mapped...

var entities = await Task.WhenAll(dtos.Select(dto => dbContext.MapAsync<Entity>(dto)));

GraphQL and Detached mapper

Hi,

I'm trying to create a POC in .NET 7 using HotChocolate and EF Core.

Entities from Db Context are used directly as DTOs and detached mapper has been configured as follows:

Program.cs:

builder.Services.AddDbContext<DatabaseDbContext>(
    options =>
    {
        options.UseMapping(mapping => mapping.Default(cfg => { }));

        options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))
            .UseModel(DatabaseDbContextModel.Instance);
    });

_context.Update(entity); in generic repository Update method has been changed as follows:

public async Task<TModel> Update(TModel entity)
{
     //_context.Update(entity);
     await _context.MapAsync<TModel>(entity);
     await _context.SaveChangesAsync();
     return entity;
}

But during await _context.MapAsync<TModel>(entity); i got an error of already existing entity that strangely doesn't appear anywhere in child object.

I would like to know, before investigating further in Data Model, if i've missed something about configuration through the documentation.

_context.Update(entity); works correctly Adding or Updating entities but without deleting entities in sub collections. That's why i would like to try Detached Mapper

.net6 results in error

Hi, Because .net6 is released now. I wanted to test detached-mapper and this results in the following error (used with entity framework)

System.TypeLoadException: 'Method 'GetServiceProviderHashCode' in type 'Detached.Mappers.EntityFramework.Extensions.DetachedDbContextOptionsExtensionInfo' from assembly 'Detached.Mappers.EntityFramework, Version=5.0.23.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.'

Related parent - child not processed

Sorry to bother again... This is kind of a follow-up of #41.

I am using a generic repository, when updating parent/child like in issue 41 that seems to work. But when I try to update a parent/child (parent is new / child exists). The relation on the child is not saved to DB.

This is my AddAsync with a dbresult to check for the result in DB:
image

After saving the changes this is the result:
image

Variables:
obj = object which should be persisted
dbresult = result of db query after saving
result = mapper result

[BUG] Updating related entity completely remove parent entity

Description

If I try to update Modification entity without relation fields - all fine.
But if I pass collection of Option - I have an exception and my existing Modification record in DB are gone.
Also I've tried to add [Aggregate] or [Composition] to Options field and add to MapAsync in controller second parameter with new MapperParameters { AggregationAction = AggregationAction.Map} - result the same...

Steps to reproduce

  1. In a Startup.cs
        services
                .AddControllers()
                .AddNewtonsoftJson(o =>
                {
                    ...
                    o.SerializerSettings.Converters.Add(new PatchJsonConverter(new AnnotationPatchTypeInfoProvider()));
                })
  1. Models
    [UsePatch]
    public class Modification : IHasId
    {
        public virtual int Id { get; set; }
        ...
        public virtual List<Option>? Options { get; set; }
        ...
    }

    [UsePatch]
     public class Option : IHasId
     {
        public virtual int Id { get; set; }
        public virtual string Value { get; set; }
        public virtual int ModificationId { get; set; }
     }

My env:

net5.0
ef core 5.0.10
npgsql 5.0.10
Detached-Mapper 5.0.22
Detached-PatchTypes 5.0.2

Exception

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.
   at Npgsql.EntityFrameworkCore.PostgreSQL.Update.Internal.NpgsqlModificationCommandBatch.ConsumeAsync(RelationalDataReader reader, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(DbContext _, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at magazine.Controllers.OData.ModificationController.Patch(Modification modification, CancellationToken ctx) in D:\projects\magazine\magazine\Controllers\OData\ModificationController.cs:line 57
   at lambda_method630(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)

Support filtered Include in Projection (Filter the entity graph)

var products = _context.Project<Product, ProductDto>(_context.Products
          .Include(x => x.Customers.Where(x => x.CustomerId == parameters.CustomerId)));

I wonder if there is a way to do what i want to do. Because due to its nature Project will load the entire graph, but I only want the ones where my condition matches.

Even if it already exists and i dont see it this would be a very nice feature.

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.