Open Closed

How To Create Self Referencing Attribute Foreign Key #10787


User avatar
0
johnsonlim created

Hi All, I tried to create a Self Referencing Foreign Key named "Attribute A+" in table "A" via ABP Suites. After creating the attribute, i learn that the attribute is not created automatically in database as usual even though i have Create Backend, Add Migration, Update Database options checked in ABP Suites. Apart of that, i learn that name of the attribute "Attribute A+" is not kept in ABP Suites after close and reopen. I named the attribute as such "Attribute A+" because ABP Suites does not allow the same name of 2 attribute. I did this under Advanced tab in Navigation Property page.Attahced picture with red highlighed red box is where i fill in the name.

My question is does ABP Suites support Self Referencing Foreign Key? Because apparently it seems to me no. And if ABP Suites does not support,can anyone suggest workaround?

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

7 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • ABP Suite can generate “normal” navigation properties (1-N / N-1) between two different entities, but a self-referencing relationship (an entity that has a FK to itself) is not reliably supported by Suite’s CRUD generator. The symptoms you described (not creating the FK/migration as expected, and the custom “Property name” not being persisted especially with a + suffix) are consistent with Suite not handling that scenario well.
    • Workaround (recommended): implement the self-reference manually in your EF Core model and run migrations yourself (you can still use Suite for the rest of the CRUD scaffolding, but don’t rely on it to model this relationship).

    Manual self-referencing FK (EF Core) example

    Assume entity A should optionally reference a parent A:

    1) Domain entity (A.cs)

    public class A : AggregateRoot<Guid>
    {
        public Guid? ParentAId { get; set; }   // FK column
        public A? ParentA { get; set; }        // reference nav
    
        public ICollection<A> ChildAs { get; set; } = new List<A>(); // collection nav
    }
    

    2) EF Core mapping (in your OnModelCreating / DbContextModelCreatingExtensions)

    builder.Entity<A>(b =>
    {
        b.HasOne(x => x.ParentA)
         .WithMany(x => x.ChildAs)
         .HasForeignKey(x => x.ParentAId)
         .OnDelete(DeleteBehavior.Restrict); // common choice to avoid cascade cycles
    });
    

    3) Add migration + update DB Run the standard EF Core migration commands (or use your DbMigrator project) so the column and FK constraint are created.

    Important notes for your specific case

    • Do not use special characters like + in property names (Attribute A+). That is not a valid C# identifier and will cause persistence/generation issues in tooling. Use a valid identifier such as ParentA, ParentAId, AttributeAPlus, etc.
    • If you need two separate self-references (e.g., ParentAId and AlternateParentAId), name them explicitly with valid identifiers and map both relationships in EF Core; Suite typically struggles even more with “multiple relationships to the same entity” scenarios.

    Sources

    • https://abp.io/docs/latest/suite/generating-crud-page
    • https://abp.io/community/articles/furp75ex

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Hi,

    ABP Suite can scaffold a self-referencing relationship, but on SQL Server this flow needs a small workaround. Two things are happening in your case.

    First, the property name. Attribute A+ isn't a valid C# identifier (a space and + aren't allowed), so the generated code doesn't compile and generation fails before anything reaches the database. Give the navigation property a valid, unique name instead — Suite won't allow two properties with the same name, so use something like ParentId.

    So: add a navigation property, select A itself as the target entity, set the property name to ParentId, pick a display property, and leave it optional if a root row can have no parent.

    Second, the delete behavior (SQL Server only). Suite generates the self-reference with DeleteBehavior.SetNull, and SQL Server rejects SET NULL (and CASCADE) on a self-referencing foreign key — Update Database fails with error 1785 ("may cause cycles or multiple cascade paths"). So on SQL Server:

    1. Generate the backend with the valid name (leave "Update Database" unchecked for now).
    2. Find that relationship in the generated DbContext and change SetNull to NoAction:
    builder.Entity<A>(b =>
    {
        b.HasOne<A>().WithMany().HasForeignKey(x => x.ParentId)
         .OnDelete(DeleteBehavior.NoAction);
    });
    
    1. Add the migration and update the database with the EF CLI. If Suite already left a migration that failed, remove it first:
    dotnet ef migrations remove
    dotnet ef migrations add Added_A
    dotnet ef database update
    

    Don't re-run Suite generation after this edit, or it will overwrite the DbContext back to SetNull.

    One thing to keep in mind with NoAction: the database won't auto-null or auto-delete child rows, so before deleting a parent you'll need to reassign or remove its children first, otherwise the delete is rejected.

    To confirm this matches your setup, could you share:

    • Your database provider, and both the ABP and ABP Suite/CLI versions.
    • The full generation/build log (not just the popup message).
    • The generated builder.Entity<A>(...) block, and — if a migration was created — its AddForeignKey / onDelete line.

    Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    johnsonlim created

    [AI-Bot] said:

    • ABP Suite can generate “normal” navigation properties (1-N / N-1) between two different entities, but a self-referencing relationship (an entity that has a FK to itself) is not reliably supported by Suite’s CRUD generator. The symptoms you described (not creating the FK/migration as expected, and the custom “Property name” not being persisted especially with a + suffix) are consistent with Suite not handling that scenario well.
    • Workaround (recommended): implement the self-reference manually in your EF Core model and run migrations yourself (you can still use Suite for the rest of the CRUD scaffolding, but don’t rely on it to model this relationship).

    Manual self-referencing FK (EF Core) example

    Assume entity A should optionally reference a parent A:

    1) Domain entity (A.cs)

    public class A : AggregateRoot<Guid> 
    { 
        public Guid? ParentAId { get; set; }   // FK column 
        public A? ParentA { get; set; }        // reference nav 
     
        public ICollection<A> ChildAs { get; set; } = new List<A>(); // collection nav 
    } 
    

    2) EF Core mapping (in your OnModelCreating / DbContextModelCreatingExtensions)

    builder.Entity<A>(b => 
    { 
        b.HasOne(x => x.ParentA) 
         .WithMany(x => x.ChildAs) 
         .HasForeignKey(x => x.ParentAId) 
         .OnDelete(DeleteBehavior.Restrict); // common choice to avoid cascade cycles 
    }); 
    

    3) Add migration + update DB Run the standard EF Core migration commands (or use your DbMigrator project) so the column and FK constraint are created.

    Important notes for your specific case

    • Do not use special characters like + in property names (Attribute A+). That is not a valid C# identifier and will cause persistence/generation issues in tooling. Use a valid identifier such as ParentA, ParentAId, AttributeAPlus, etc.
    • If you need two separate self-references (e.g., ParentAId and AlternateParentAId), name them explicitly with valid identifiers and map both relationships in EF Core; Suite typically struggles even more with “multiple relationships to the same entity” scenarios.

    Sources

    • https://abp.io/docs/latest/suite/generating-crud-page
    • https://abp.io/community/articles/furp75ex

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Hi, My another question is that by by doing the changes in code, one day in future, if i use the ABP Suite to generate additional attribute, will i lost the code and the foreign key relation?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • Yes, you can lose (have overwritten) your manual EF Core mapping changes if ABP Suite re-generates the same area again. Suite’s “Save and generate” can rewrite generated files (including the DbContext / entity mapping blocks it generated), so a manual change like switching OnDelete(DeleteBehavior.SetNull) to NoAction/Restrict may be reverted on the next generation.

    • However, your database foreign key will not disappear by itself just because Suite generates more code. The DB schema only changes when you add/apply a new migration (or drop/recreate/update DB). The main risk is: future generation overwrites your mapping, and then your next migration may try to alter the FK behavior again (or you may start getting migration/update failures again).

    What to do to avoid losing it

    1. Keep the self-referencing relationship mapping in a place Suite won’t touch, and keep Suite-generated code minimal. Practically:
      • Prefer to configure your self-reference in your own mapping code under OnModelCreating (or the project’s ConfigureYourProjectName() style extension method), not in a file that Suite repeatedly regenerates for the entity.
    2. If you must let Suite generate again, be prepared to re-apply the DeleteBehavior fix after generation (and before creating the next migration).
    3. Version control is your safety net: after any Suite generation, review the diff and restore your custom mapping if Suite overwrote it.

    Sources

    • https://abp.io/docs/latest/suite/generating-crud-page
    • https://abp.io/docs/latest/solution-templates/layered-web-application/database-configurations
    • https://abp.io/community/articles/furp75ex

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    johnsonlim created

    [AI-Bot] said:

    • Yes, you can lose (have overwritten) your manual EF Core mapping changes if ABP Suite re-generates the same area again. Suite’s “Save and generate” can rewrite generated files (including the DbContext / entity mapping blocks it generated), so a manual change like switching OnDelete(DeleteBehavior.SetNull) to NoAction/Restrict may be reverted on the next generation.

    • However, your database foreign key will not disappear by itself just because Suite generates more code. The DB schema only changes when you add/apply a new migration (or drop/recreate/update DB). The main risk is: future generation overwrites your mapping, and then your next migration may try to alter the FK behavior again (or you may start getting migration/update failures again).

    What to do to avoid losing it

    1. Keep the self-referencing relationship mapping in a place Suite won’t touch, and keep Suite-generated code minimal. Practically:
      • Prefer to configure your self-reference in your own mapping code under OnModelCreating (or the project’s ConfigureYourProjectName() style extension method), not in a file that Suite repeatedly regenerates for the entity.
    2. If you must let Suite generate again, be prepared to re-apply the DeleteBehavior fix after generation (and before creating the next migration).
    3. Version control is your safety net: after any Suite generation, review the diff and restore your custom mapping if Suite overwrote it.

    Sources

    • https://abp.io/docs/latest/suite/generating-crud-page
    • https://abp.io/docs/latest/solution-templates/layered-web-application/database-configurations
    • https://abp.io/community/articles/furp75ex

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    If there is possibilty of code overwritting, shall i proceed?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent

    Proceed, but proceed with one rule: treat ABP Suite output as regeneratable scaffolding, and keep your manual EF Core mapping in “custom-owned” files/sections so Suite won’t overwrite it.

    What that means in practice:

    • It’s safe to continue using Suite to add new properties / generate UI / app services.
    • Do not rely on Suite to preserve manual edits inside the generated mapping block for that entity. If you edit a Suite-managed file, it can be overwritten when you click Save and generate again for the same entity.

    A safe workflow

    1. Use Suite to generate the entity (with a valid C# property name like ParentId).
    2. Apply your self-referencing FK fix (e.g., DeleteBehavior.NoAction/Restrict) in a customization location you own (a separate mapping extension method / separate file that you keep under source control).
    3. After future Suite generations, verify the mapping didn’t get reverted before creating a new migration.
    4. Use git diff as the guardrail.

    Why this is still worth doing

    • The database foreign key won’t change unless you create/apply a migration.
    • The only real risk is future regeneration reverting the model configuration, which then affects future migrations (or causes SQL Server cascade-path errors again). Keeping the fix in your own code avoids that.

    (Links below are verified accessible.)

    • https://abp.io/docs/latest/suite/generating-crud-page
    • https://abp.io/docs/latest/solution-templates/layered-web-application/database-configurations

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Hi,

    Yes — that change lives in code Suite regenerates. When you run generation again for this entity (e.g. to add another property), Suite rewrites the entity's relationship configuration in the DbContext, so your NoAction gets reverted to SetNull. Suite's "customizable code" only preserves specific custom-code regions in the generated classes (like the entity/service constructors); it doesn't cover the DbContext relationship mapping.

    Your database foreign key won't disappear when Suite regenerates the code, because regeneration doesn't change the database schema. But if you add a migration after the mapping has been reverted to SetNull, that migration will try to change the foreign key back to SetNull, and applying it on SQL Server will fail with error 1785.

    So the practical approach: after re-generating this entity, re-apply the NoAction line before you add the migration. If the project is under source control, the revert shows up clearly in the diff, so it's a quick thing to restore each time.

    We'll also review this behavior in Suite so self-referencing relationships can use a SQL Server-compatible delete behavior by default.

    Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
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.8.0-preview. Updated on September 28, 2026, 11:44
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.