Inverse Property in EF Core

Prathamesh Shende 381 Reputation points
2021-10-23T21:27:16.837+00:00

How to apply Inverse Property in Ef Core I gone through so many examples but didnt helps me. So

my models like this
public class Customer
{

    public string Name { get; set; }
    public int AddedByID { get; set; }
    public int EditedByID { get; set; }
    public int DeletedByID { get; set; }
    [InverseProperty("Customers")]
    [ForeignKey("AddedByID")]
    public virtual UserLogin AddedBy { get; set; }
    [ForeignKey("EditedByID")]
    public virtual UserLogin EditedBy { get; set; }
    [ForeignKey("DeletedByID")]
    public virtual UserLogin DeletedBy { get; set; }

}
public class Vendor
{

    public string Name { get; set; }
    public int AddedByID { get; set; }
    public int EditedByID { get; set; }
    public int DeletedByID { get; set; }
    [InverseProperty("Vendors")]
    [ForeignKey("AddedByID")]
    public virtual UserLogin AddedBy { get; set; }
    [ForeignKey("EditedByID")]
    public virtual UserLogin EditedBy { get; set; }
    [ForeignKey("DeletedByID")]
    public virtual UserLogin DeletedBy { get; set; }

}
public class UserLogin
{
public UserLogin()
{
Customers = new HashSet<Customer>();
Vendors = new HashSet<Vendor>();

    }

public virtual ICollection<Customer> Customers { get; set; }
public virtual ICollection<Vendor> Vendors { get; set; }
}

this only works if I use only model (Customer) if Add this same properties into vendor then it throw error - Unable to determine the relationship represented by navigation 'Custom.Edited By' of type 'UserLogin'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.'

this error is not show if I dont use vendor model

so How do I apply inverse property here

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,779 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Zhi Lv - MSFT 32,941 Reputation points Microsoft Vendor
    2021-10-25T06:08:13.607+00:00

    Hi @Prathamesh Shende ,

    You can set the foreign key to nullable and use InverseProperty as below:

    public class Customer  
    {  
        [Key]  
        public int ID { get; set; }  
        public string Name { get; set; }  
        [ForeignKey("AddedBy")]  
        public int? AddedByID { get; set; }  
        [ForeignKey("EditedBy")]  
        public int? EditedByID { get; set; }  
        [ForeignKey("DeletedBy")]  
        public int? DeletedByID { get; set; }   
        public UserLogin AddedBy { get; set; }   
        public UserLogin EditedBy { get; set; }   
        public UserLogin DeletedBy { get; set; }  
    }  
    public class Vendor  
    {  
        [Key]  
        public int ID { get; set; }  
        public string Name { get; set; }  
        [ForeignKey("AddedBy")]  
        public int? AddedByID { get; set; }  
        [ForeignKey("EditedBy")]  
        public int? EditedByID { get; set; }  
        [ForeignKey("DeletedBy")]  
        public int? DeletedByID { get; set; }   
        public UserLogin AddedBy { get; set; }  
        public UserLogin EditedBy { get; set; }  
        public UserLogin DeletedBy { get; set; }  
    }  
    public class UserLogin  
    {   
        public UserLogin()  
        {  
            CustomersAdded = new List<Customer>();  
            VendorsAdded = new List<Vendor>();  
        }  
    
        [Key]  
        public int Id { get; set; }  
        public string Name { get; set; }  
    
        [InverseProperty("AddedBy")]  
        public List<Customer> CustomersAdded { get; set; }  
        [InverseProperty("EditedBy")]  
        public List<Customer> CustomersEdited { get; set; }  
        [InverseProperty("DeletedBy")]  
        public List<Customer> CustomersDeleted { get; set; }  
        [InverseProperty("AddedBy")]  
        public List<Vendor> VendorsAdded { get; set; }  
        [InverseProperty("EditedBy")]  
        public List<Vendor> VendorsEdited { get; set; }  
        [InverseProperty("DeletedBy")]  
        public List<Vendor> VendorsDeleted { get; set; }  
    }  
    

    And configure the cascading delete as NoAction:

    public class ApplicationDbContext : IdentityDbContext  
    {  
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)  
            : base(options)  
        {  
        }    
    
        public DbSet<UserLogin> UserLogin { get; set; }  
        public DbSet<Customer> Customers { get; set; }  
        public DbSet<Vendor> Vendors { get; set; }  
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)  
        {  
            base.OnModelCreating(modelBuilder);  
            modelBuilder.Entity<Customer>()  
                .HasOne(c => c.AddedBy)  
                .WithMany(c=>c.CustomersAdded)  
                .OnDelete(DeleteBehavior.NoAction);  
            modelBuilder.Entity<Customer>()  
                .HasOne(c => c.EditedBy)  
               .WithMany(c => c.CustomersEdited)  
                .OnDelete(DeleteBehavior.NoAction);  
            modelBuilder.Entity<Customer>()  
                .HasOne(c => c.DeletedBy)  
               .WithMany(c => c.CustomersDeleted)  
                .OnDelete(DeleteBehavior.NoAction);  
            modelBuilder.Entity<Vendor>()  
                .HasOne(c => c.AddedBy)  
               .WithMany(c => c.VendorsAdded)  
                .OnDelete(DeleteBehavior.NoAction);  
            modelBuilder.Entity<Vendor>()  
                .HasOne(c => c.EditedBy)  
                .WithMany(c=>c.VendorsEdited)  
                .OnDelete(DeleteBehavior.NoAction);  
            modelBuilder.Entity<Vendor>()  
                .HasOne(c => c.DeletedBy)  
                .WithMany(c=>c.VendorsDeleted)  
                .OnDelete(DeleteBehavior.NoAction);   
        }  
    }  
    

    The generated table as below:

    143324-image.png

    Then, you can add/remove the entity via the ApplicationDbContext, like this:

            _context.UserLogin.Add(new UserLogin()  
            {  
               Name="AA",  
               CustomersAdded= new List<Customer>()  
               {  
                   new Customer(){ Name="Tom"}  
               },  
                CustomersEdited = new List<Customer>()  
               {  
                   new Customer(){ Name="John"}  
               },  
                VendorsAdded = new List<Vendor>()  
                {  
                    new Vendor(){ Name="Jack"}  
                }  
            });  
            _context.SaveChanges();  
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.