Hi, @EngincanV thanks for the response.
I tested the change with the steps you mentioned and it did work, that is, the table created in the previous module is no longer created again in the migration for the new module.
However, I noticed that this only worked when I ran the command to remove the latest migration twice (as you instructed), and as expected that removes the last two migrations, even though the second to last migration it removes has no relation to the latest one or its tables. I don't understand why that is the case, could you please provide an explanation?
Thanks in advance.
Hi, sometimes when adding a new migration there might occur some sync problems between following migrations (due to old assemblies, even the command build the efcore project still some assemblies may old assemblies for example) and it seems this was the case in your example, because your configuration was right.
So by reverting the last two migration, you have sync the migrations and so the efcore could generate a new migration from the right point and sync itself.
Support, please support.
Hi, since the question was asked by @bmulinari and you have added the last response, questions become invisible from our dashboard. This is the reason why we could not prioritize to answer this question. Sorry for the late response.
@bmulinari can you please send the project again, because when I try to download the application, it gives a 502 bad gateway error? I have reviewed it before but I could not find it in my workspace for now.
I will prioritize it and will fix your problem when you send your email. So, please let me know.
Regards.
@EngincanV, I have sent the e-mail again with the code.
Hi, thanks for sharing your project. I have sent an email to you with a solution to your problem:
Please check your mail and let me know if you need further assistant. Regards.
Support, please support.
Hi, since the question was asked by @bmulinari and you have added the last response, questions become invisible from our dashboard. This is the reason why we could not prioritize to answer this question. Sorry for the late response.
@bmulinari can you please send the project again, because when I try to download the application, it gives a 502 bad gateway error? I have reviewed it before but I could not find it in my workspace for now.
I will prioritize it and will fix your problem when you send your email. So, please let me know.
Regards.
This ticket has been open over 2 weeks, we would appreciate some feedback
Hi, sorry for the late response. I will write you back soon.
Regards.
BTW, the name of this thread should probably change now in 2025.
Thanks for reminding. I'm closing this thread and creating a fresh one, which you can follow at https://abp.io/support/questions/8803/ABP-Suite-feature-request--2025
We have created internal issues for ABP Suite related feature-requests and will consider them and try to implement them in our each version. Thank you all for your interest and if you still have new feature-request, please list them in the new thread.
Best Regards.
Hi @EngincanV,
Hi, since in your entity configuration the UserProfile has a not nullable UserId field you can't set the user.Profile as null without deleting the userProfile.
Added a new DeleteProfile method in user repository:
public class EfCoreUserRepository : EfCoreRepository<AbpEFCorePlaygroundDbContext, User, Guid>, IUserRepository { public EfCoreUserRepository( IDbContextProvider<AbpEFCorePlaygroundDbContext> dbContextProvider) : base(dbContextProvider) { } public async Task DeleteProfileAsync(User user) { if (user.Profile == null) { return; } AbpEFCorePlaygroundDbContext dbContext = await GetDbContextAsync(); dbContext.Remove(user.Profile); user.Profile = null; } }Update in app service:
public async Task DeleteUserProfileAsync() { var user = await _userRepository.GetAsync(x => x.Id == Guid.Parse("c64b873e-c067-43e0-ae00-07992a880837")); if (user.Profile == null) { return; } await _userRepository.DeleteProfileAsync(user); await _userRepository.UpdateAsync(user); }The user updated event is correct:
But when I continue after the breakpoint, the request still keeps executing, because of the infinite loop in the AbpDbContext:
![]()
And the user profile is not deleted in the database.
Best regards, Steff Beckers
Hi, the problem in your code is that both the User and the UserProfile entities use the soft-delete, which means when you delete a user profile, it's not deleted in normally, only its IsDeleted field set to true and it becomes invisible in your SQL queries, if you apply dataFilters and ABP applies it by default (https://abp.io/docs/9.0/framework/infrastructure/data-filtering#isoftdelete). Therefore, you can't set the user.Profile as null, because the profile is soft-deleted, not hard-deleted. This is the difference between your EfCorePlayground and AbpEfCorePlayground applications.
If you want the UserProfile as hard deleted, then you can use the IDataFilter service. Example:
private readonly IDataFilter _dataFilter;
using (_dataFilter.Disable<ISoftDelete>())
{
//hard deletes from your db
await _userProfileRepository.DeleteAsync(user.Profile!.Id, autoSave: true);
}
Hi, since in your entity configuration the UserProfile has a not nullable UserId field you can't set the user.Profile as null without deleting the userProfile.
Hi @EngincanV,
and make the UserId as nullable
A UserProfile record can't exist without a reference to a User, so the UserId on UserProfile should not be nullable.
Best regards, Steff Beckers
Hi, then you can directly delete the userProfile instead of setting user.Profile as null. This is the only solution. If you want to set the user's profile as null it should be nullable, or if you directly delete the profile, it will be empty further on.
Regards.
Hello,
I looked over the documentation that you sent and tried using the Audited attribute, but this did not give me what I was looking for.
I am trying to manually add a history log entry to our User entity for changes that are not occurring in the User table. The changes occur on our UserAssignedMerchant join table.
Here is some additional context on our User implementation:
- We implemented our own User class and dtos, but are using IdentityUserManager calls that we adapted from source code to set the properties to still use the built in AbpUsers table and features in our create and update methods.
- Also during those methods, we set the entries in the join table with repository calls for the join table.
- We give the UserAssignedMerchant entries to the end users in a field that is a Guid[] called AssignedMerchantIds, but this only on the dto not the class so it's manually set at the time of retrieval.
Is there a repository call (such as through IAuditLogRepository) that we can make to insert a history log on User that will allow us to manually set what changed in AssignedMerchantIds? Or is there a better way to accomplish this?
Thanks.
Hi, you can configure the AbpAuditingOptions and define an EntityHistorySelector as below:
opt.EntityHistorySelectors.Add(
new NamedTypeSelector(
"UserAssignedMerchant",
type => typeof(UserAssignedMerchant).IsAssignableFrom(type)
));
Hi @EngincanV,
Hi, based on your EfCorePlayground project, you can call _context.UserProfiles.Remove(user.Profile!) method before setting user.Profile to null:
The EfCorePlayground project doesn't have the issue, the AbpEfCorePlayground project has.
Best regards, Steff Beckers
Hi, here is what you need to do to:
1 -) In your UserProfile entity, remove the Id property (because it's already defined by the base class FullAuditedEntity<Guid>), and make the UserId as nullable:
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; }
}
2-) Open your dbcontext class and update the configuration:
b.HasOne(x => x.Profile)
.WithOne(x => x.User)
.HasForeignKey<UserProfile>(x => x.UserId)
.OnDelete(DeleteBehavior.ClientSetNull);
You should use the
ClientSetNullas the delete-behaviour, which is default and allows you to set the Profile as null.
3-) Update your DeleteUserProfileAsync method:
public async Task DeleteUserProfileAsync()
{
var user = await _userRepository.GetAsync(x => x.Id == Guid.Parse("c64b873e-c067-43e0-ae00-07992a880837"));
await _userProfileRepository.DeleteAsync(user.Profile!.Id);
user.Profile = null;
await _userRepository.UpdateAsync(user);
}
Then, it will work as you expected.
Regards.