Activities of "s.beckers"

Hi @EngincanV,

I have created a 3rd example app, of the User & UserProfile example inside an ABP framework solution: https://cdn.fuzed.app/share/abp/AbpEFCorePlayground.zip

This time the SQL query loop occurs again, within ABP framework, using the same configuration as previous example. So I think this is some framework issue that needs to be fixed.

User entity:

using System;
using Volo.Abp.Domain.Entities.Auditing;

namespace AbpEFCorePlayground.Users;

public class User : FullAuditedAggregateRoot<Guid>
{
    public User(
        Guid id,
        string name)
    {
        Id = id;
        Name = name;
    }

    private User()
    {
    }

    public string Name { get; set; }

    public UserProfile? Profile { get; set; }
}

UserProfile entity:

using System;
using Volo.Abp.Domain.Entities.Auditing;

namespace AbpEFCorePlayground.Users;

public class UserProfile : FullAuditedEntity<Guid>
{
    public Guid Id { get; set; }

    public string Bio { get; set; }

    public Guid UserId { get; set; }

    public User User { get; set; }
}

UsersDataSeedContributor:

using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;

namespace AbpEFCorePlayground.Users;

public class UsersDataSeedContributor : IDataSeedContributor, ITransientDependency
{
    private readonly IUserRepository _userRepository;

    public UsersDataSeedContributor(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    [UnitOfWork]
    public virtual async Task SeedAsync(DataSeedContext context)
    {
        User user = new User(
            id: Guid.Parse("c64b873e-c067-43e0-ae00-07992a880837"),
            name: "Steff Beckers")
        {
            Profile = new UserProfile()
            {
                Bio = "Software Developer"
            }
        };

        await _userRepository.DeleteAsync(x => x.Id == user.Id);
        await _userRepository.InsertAsync(user);
    }
}

EF entity configuration:

        builder.Entity<User>(b =>
        {
            b.ToTable(AbpEFCorePlaygroundConsts.DbTablePrefix + "Users", AbpEFCorePlaygroundConsts.DbSchema);
            b.ConfigureByConvention(); //auto configure for the base class props

            b.HasOne(x => x.Profile)
                .WithOne(x => x.User)
                .HasForeignKey<UserProfile>(x => x.UserId)
                .IsRequired()
                .OnDelete(DeleteBehavior.Cascade);
        });

        builder.Entity<UserProfile>(b =>
        {
            b.ToTable(AbpEFCorePlaygroundConsts.DbTablePrefix + "UserProfiles", AbpEFCorePlaygroundConsts.DbSchema);
            b.ConfigureByConvention(); //auto configure for the base class props
        });
        
        Configure<AbpEntityOptions>(options =>
        {
            options.Entity<User>(e =>
            {
                e.DefaultWithDetailsFunc = query => query.Include(x => x.Profile);
            });
        });

App service:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbpEFCorePlayground.Users;

public class UsersAppService : AbpEFCorePlaygroundAppService, IUsersAppService
{
    private readonly IUserRepository _userRepository;

    public UsersAppService(IUserRepository userRepository)
    {
        this._userRepository = userRepository;
    }

    public async Task DeleteUserProfileAsync()
    {
        var user = await _userRepository.GetAsync(x => x.Id == Guid.Parse("c64b873e-c067-43e0-ae00-07992a880837"));

        user.Profile = null;

        await _userRepository.UpdateAsync(user);
    }
}

Best regards, Steff Beckers

Hi @EngincanV,

I've tested IsRequired(false) and it solves the query issue, but the Author itself isn't deleted. An author can't exist on its own in this case and now we have a "ghost" Author record, since BookId is now allowed to be NULL. So I don't think we should use IsRequired(false). IsRequired configures whether this is a required relationship (i.e. whether the foreign key property(s) can be assigned null). It doesn't ensure that a Book requires an Author. It only ensures that the FK is required/can't be NULL => an Author must have a BookId.

Also see the EF core docs: https://learn.microsoft.com/en-us/ef/core/modeling/relationships/one-to-one#required-one-to-one

I've created a new and better (relation wise) example using the ASP.NET Core Web API template, where the removal works as expected: https://cdn.fuzed.app/share/abp/EFCorePlayground.zip

Entities:

public class User
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public UserProfile? Profile { get; set; }
}

public class UserProfile
{
    public Guid Id { get; set; }

    public string Bio { get; set; }

    public Guid UserId { get; set; }

    public User User { get; set; }
}

DbContext:

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    public DbSet<User> Users { get; set; }

    public DbSet<UserProfile> UserProfiles { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .HasOne(x => x.Profile)
            .WithOne(x => x.User)
            .HasForeignKey<UserProfile>(x => x.UserId)
            .IsRequired()
            .OnDelete(DeleteBehavior.Cascade);
    }
}

Controller:

[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
    private readonly AppDbContext _context;

    public UsersController(AppDbContext context)
    {
        _context = context;
    }

    ...

    // DELETE: api/users/{id}/profile
    [HttpDelete("{id}/profile")]
    public async Task<IActionResult> DeleteUserProfile(Guid id)
    {
        User? user = await _context.Users.Include(x => x.Profile).FirstOrDefaultAsync(x => x.Id == id);
        if (user == null)
        {
            return NotFound();
        }

        user.Profile = null;

        await _context.SaveChangesAsync();

        return NoContent();
    }
    
    ...
}

Thanks in advance!

Best regards, Steff Beckers

It seems I still had to clear my local NuGet cache to resolve the warnings.

I got the same issue

Hi

I'll try that.

Thanks!

While investigating the bundling I saw a lot of logs related to the bundling. Can you check if this is correct, since I see a lot of the same files getting bundled and minified? Or are these from multiple requests? Also, notice the timestamps.

https://cdn.fuzed.app/share/abp/main-http-api-6f5c75958b.log

Thanks!

Can you share this project or make a simple project?

I can't share our source code. With the test project I tried to create, I coudn't reproduce the same warnings..

Yes, we still can reproduce the issue in our application without SetMinThreads. When the Redis cache is cleared or expired, if we then request a web page, which triggers a lot of API requests (due loading image thumbnails), then the Redis timeout warnings are logged.

Hi @maliming, I've tried to create a test app, but I couldn't reproduce the same warnings we got from the Redis timeouts. We monitored the thread pool usage:

dotnet-counters monitor --counters System.Runtime -n Fuzed.HttpApi.Host

In the end we ended up updating the min worker threads in our app:

ThreadPool.GetMinThreads(out int minWorkerThreads, out int minCompletionPortThreads);
ThreadPool.SetMinThreads(100, minCompletionPortThreads);

Thanks!

hi @s.beckers

Can you share your test project?

liming.ma@volosoft.com

Thanks.

Hi @maliming, I'll try to create a test project and send it to you.

Showing 11 to 20 of 37 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on September 18, 2025, 07:10