Activities of "maliming"

Hi

If you can share a minimal project I can check it, maybe we can improve more performance.

Thanks

hi

Can you try to override the AbpEfCoreNavigationHelper in your project?

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;

namespace Volo.Abp.EntityFrameworkCore.ChangeTrackers;

public class MyAbpEntityEntry
{
    public string Id { get; set; }

    public EntityEntry EntityEntry { get; set; }

    public List<AbpNavigationEntry> NavigationEntries { get; set; }

    private bool _isModified;
    public bool IsModified
    {
        get
        {
            return _isModified || EntityEntry.State == EntityState.Modified || NavigationEntries.Any(n => n.IsModified);
        }
        set => _isModified = value;
    }

    public MyAbpEntityEntry(string id, EntityEntry entityEntry)
    {
        Id = id;
        EntityEntry = entityEntry;
        NavigationEntries = EntityEntry.Navigations.Select(x => new AbpNavigationEntry(x, x.Metadata.Name)).ToList();
    }

    public void UpdateNavigationEntries()
    {
        foreach (var navigationEntry in NavigationEntries)
        {
            if (IsModified ||
                EntityEntry.State == EntityState.Modified ||
                navigationEntry.IsModified ||
                navigationEntry.NavigationEntry.IsModified)
            {
                continue;
            }

            var currentValue = AbpNavigationEntry.GetOriginalValue(navigationEntry.NavigationEntry.CurrentValue);
            if (currentValue == null)
            {
                continue;
            }
            switch (navigationEntry.OriginalValue)
            {
                case null:
                    navigationEntry.OriginalValue = currentValue;
                    break;
                case IEnumerable originalValueCollection when currentValue is IEnumerable currentValueCollection:
                {
                    var existingList = originalValueCollection.Cast<object?>().ToList();
                    var newList = currentValueCollection.Cast<object?>().ToList();
                    if (newList.Count > existingList.Count)
                    {
                        navigationEntry.OriginalValue = currentValue;
                    }

                    break;
                }
                default:
                    navigationEntry.OriginalValue = currentValue;
                    break;
            }
        }
    }
}

[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(AbpEfCoreNavigationHelper))]
public class MyAbpEfCoreNavigationHelper : AbpEfCoreNavigationHelper
{
    protected Dictionary<string, MyAbpEntityEntry> MyEntityEntries { get; } = new();

    public override void ChangeTracker_Tracked(object? sender, EntityTrackedEventArgs e)
    {
        EntityEntryTrackedOrStateChanged(e.Entry);
        DetectChanges(e.Entry);
    }

    public override void ChangeTracker_StateChanged(object? sender, EntityStateChangedEventArgs e)
    {
        EntityEntryTrackedOrStateChanged(e.Entry);
        DetectChanges(e.Entry);
    }

    protected override void EntityEntryTrackedOrStateChanged(EntityEntry entityEntry)
    {
        if (entityEntry.State != EntityState.Unchanged)
        {
            return;
        }

        var entryId = GetEntityEntryIdentity(entityEntry);
        if (entryId == null)
        {
            return;
        }

        if (MyEntityEntries.ContainsKey(entryId))
        {
            return;
        }

        MyEntityEntries.Add(entryId, new MyAbpEntityEntry(entryId, entityEntry));
    }

    protected override void DetectChanges(EntityEntry entityEntry, bool checkEntityEntryState = true)
    {
        #pragma warning disable EF1001
        var stateManager = entityEntry.Context.GetDependencies().StateManager;
        var internalEntityEntityEntry = stateManager.TryGetEntry(entityEntry.Entity, throwOnNonUniqueness: false);
        if (internalEntityEntityEntry == null)
        {
            return;
        }

        var foreignKeys = entityEntry.Metadata.GetForeignKeys().ToList();
        foreach (var foreignKey in foreignKeys)
        {
            var principal = stateManager.FindPrincipal(internalEntityEntityEntry, foreignKey);
            if (principal == null)
            {
                continue;
            }

            var entryId = GetEntityEntryIdentity(principal.ToEntityEntry());
            if (entryId == null || !MyEntityEntries.TryGetValue(entryId, out var myAbpEntityEntry))
            {
                continue;
            }

            myAbpEntityEntry.UpdateNavigationEntries();
            if (!myAbpEntityEntry.IsModified && (!checkEntityEntryState || IsEntityEntryChanged(entityEntry)))
            {
                myAbpEntityEntry.IsModified = true;
                DetectChanges(myAbpEntityEntry.EntityEntry, false);
            }

            var navigationEntry = myAbpEntityEntry.NavigationEntries.FirstOrDefault(x => x.NavigationEntry.Metadata is INavigation navigationMetadata && navigationMetadata.ForeignKey == foreignKey) ??
                                  myAbpEntityEntry.NavigationEntries.FirstOrDefault(x => x.NavigationEntry.Metadata is ISkipNavigation skipNavigationMetadata && skipNavigationMetadata.ForeignKey == foreignKey);
            if (navigationEntry != null && IsEntityEntryChanged(entityEntry))
            {
                navigationEntry.IsModified = true;
            }
        }

        var skipNavigations = entityEntry.Metadata.GetSkipNavigations().ToList();
        foreach (var skipNavigation in skipNavigations)
        {
            var joinEntityType = skipNavigation.JoinEntityType;
            var foreignKey = skipNavigation.ForeignKey;
            var inverseForeignKey = skipNavigation.Inverse.ForeignKey;
            foreach (var joinEntry in stateManager.Entries)
            {
                if (joinEntry.EntityType != joinEntityType || stateManager.FindPrincipal(joinEntry, foreignKey) != internalEntityEntityEntry)
                {
                    continue;
                }

                var principal = stateManager.FindPrincipal(joinEntry, inverseForeignKey);
                if (principal == null)
                {
                    continue;
                }

                var entryId = GetEntityEntryIdentity(principal.ToEntityEntry());
                if (entryId == null || !MyEntityEntries.TryGetValue(entryId, out var myAbpEntityEntry))
                {
                    continue;
                }

                myAbpEntityEntry.UpdateNavigationEntries();
                if (!myAbpEntityEntry.IsModified  && (!checkEntityEntryState || IsEntityEntryChanged(entityEntry)))
                {
                    myAbpEntityEntry.IsModified = true;
                    DetectChanges(myAbpEntityEntry.EntityEntry, false);
                }

                var navigationEntry = myAbpEntityEntry.NavigationEntries.FirstOrDefault(x => x.NavigationEntry.Metadata is INavigation navigationMetadata && navigationMetadata.ForeignKey == inverseForeignKey) ??
                                      myAbpEntityEntry.NavigationEntries.FirstOrDefault(x => x.NavigationEntry.Metadata is ISkipNavigation skipNavigationMetadata && skipNavigationMetadata.ForeignKey == inverseForeignKey);
                if (navigationEntry != null && (!checkEntityEntryState || IsEntityEntryChanged(entityEntry)))
                {
                    navigationEntry.IsModified = true;
                }
            }
        }
#pragma warning restore EF1001
    }

    protected override bool IsEntityEntryChanged(EntityEntry entityEntry)
    {
        return entityEntry.State == EntityState.Added ||
               entityEntry.State == EntityState.Deleted ||
               entityEntry.State == EntityState.Modified;
    }

    public override List<EntityEntry> GetChangedEntityEntries()
    {
        return MyEntityEntries
            .Where(x => x.Value.IsModified)
            .Select(x => x.Value.EntityEntry)
            .ToList();
    }

    public override bool IsEntityEntryModified(EntityEntry entityEntry)
    {
        if (entityEntry.State == EntityState.Modified)
        {
            return true;
        }

        var entryId = GetEntityEntryIdentity(entityEntry);
        if (entryId == null)
        {
            return false;
        }

        return MyEntityEntries.TryGetValue(entryId, out var myAbpEntityEntry) && myAbpEntityEntry.IsModified;
    }

    public override bool IsNavigationEntryModified(EntityEntry entityEntry, int? navigationEntryIndex = null)
    {
        var entryId = GetEntityEntryIdentity(entityEntry);
        if (entryId == null)
        {
            return false;
        }

        if (!MyEntityEntries.TryGetValue(entryId, out var myAbpEntityEntry))
        {
            return false;
        }

        if (navigationEntryIndex == null)
        {
            return myAbpEntityEntry.NavigationEntries.Any(x => x.IsModified);
        }

        var navigationEntryProperty = myAbpEntityEntry.NavigationEntries.ElementAtOrDefault(navigationEntryIndex.Value);
        return navigationEntryProperty != null && navigationEntryProperty.IsModified;
    }

    public override AbpNavigationEntry? GetNavigationEntry(EntityEntry entityEntry, int navigationEntryIndex)
    {
        var entryId = GetEntityEntryIdentity(entityEntry);
        if (entryId == null)
        {
            return null;
        }

        if (!MyEntityEntries.TryGetValue(entryId, out var myAbpEntityEntry))
        {
            return null;
        }

        return myAbpEntityEntry.NavigationEntries.ElementAtOrDefault(navigationEntryIndex);
    }

    protected override string? GetEntityEntryIdentity(EntityEntry entityEntry)
    {
        if (entityEntry.Entity is IEntity entryEntity && entryEntity.GetKeys().Length == 1)
        {
            return $"{entityEntry.Metadata.ClrType.FullName}:{entryEntity.GetKeys().FirstOrDefault()}";
        }

        return null;
    }

    public override void RemoveChangedEntityEntries()
    {
        MyEntityEntries.RemoveAll(x => x.Value.IsModified);
    }

    public override void Clear()
    {
        MyEntityEntries.Clear();
    }
}

: )

hi

This line has a performance problem. I will fix it in 9.2.3

Thanks. Your ticket has been refunded.


If you can share a minimal project, I can test it with the local ABP source code to make sure it works for you.

hi

If you can use it in an ASP.NET Core application, you can also use it in an ABP application.

You just need to check its documentation. If you run into any issues, feel free to provide feedback

Thanks.

Add Microsoft.IdentityModel with the latest version that fixes the problem.

<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect"  Version="8.12.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens"  Version="8.12.1" />
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens"  Version="8.12.1" />

hi

we only need how to configure it exactly.

You need to configure JSON options in two places.


// This is for MVC JsonSerializer
Configure<JsonOptions>(options =>
{
    options.
});


// This is for ABP JsonSerializer
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
    options.
});

hi

from a web or a public web redirect to a separated OpenIddict AuthServer, after the authority, redirected to the original the url, occurred this error

Please enable debug logs/ShowPII for web, public web, and AuthServer. Then, reproduce the problem and share all logs.txt files.

https://abp.io/support/questions/8622/How-to-enable-Debug-logs-for-troubleshoot-problems

liming.ma@volosoft.com

Thanks.

hi

I've reproduced your problem; I will fix it as soon as possible.

Thanks.

ok, I'm working on it.

Showing 1631 to 1640 of 11556 entries
Learn More, Pay Less
33% OFF
All Trainings!
Get Your Deal
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.1.0-preview. Updated on December 17, 2025, 07:08
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.