Answered by:
How to add 2 foreign keys and their corresponding navigation properties to a model

Question
-
User-186068080 posted
Hi all
I a newcomer in asp.net mvc and i got stuck with a trivial problem for hours. I have a simple class that models a message. its here:
public class Message { [Key] public int Id { get; set; } // AspNetUsers public ApplicationUser Sender { get; set; } public ApplicationUser Receiver { get; set; } // SenderId of the message [Required] [ForeignKey("Sender")] [Display(Name = "Sender")] [InverseProperty("MessageSenderId")] public string SenderId { get; set; } // ReceiverId of this message [Required] [ForeignKey("Receiver")] [Display(Name = "Receiver")] [InverseProperty("MessageReceiverId")] public string ReceiverId { get; set; } // other properties }
The SenderId and ReceiverId are the Id of sender and receiver of this message respectively. The Sender and Receiver are navigation properties to fetch them from database when i want to pass the message model to view.
Unfortunately, when i want to add a new migration, this error is raised: The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_dbo.Mails_dbo.AspNetUsers_ReceiverId". The conflict occurred in database "DbName", table "dbo.AspNetUsers", column 'Id'.
The message class before changing was:
public class Message { public int Id { get; set; } // No Navigation is defined // SenderId of the message [Required] [Display(Name = "Sender")] public string SenderId { get; set; } // ReceiverId of this message [Required] [Display(Name = "Receiver")] public string ReceiverId { get; set; } // other properties }
What can i do? Thanks
Sunday, February 4, 2018 10:42 AM
Answers
-
User-832373396 posted
Hi Ehsan,
How to add 2 foreign keys and their corresponding navigation properties to a modelPlease change a bit to your current code, then it will work.
Here is the testing working example;
- 1 find the class ApplicationUser and add navigation properties ;
public class ApplicationUser : IdentityUser { public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, authenticationType); // Add custom user claims here return userIdentity; } [InverseProperty("Sender")] public virtual ICollection<Message> SenderMessages { get; set; } [InverseProperty("Receiver")] public virtual ICollection<Message> ReceiverMessages { get; set; } }
- 2 remove InverseProperty attribute to SenderId and ReceiverId
public class Message { [Key] public int Id { get; set; } // AspNetUsers public virtual ApplicationUser Sender { get; set; } public virtual ApplicationUser Receiver { get; set; } // SenderId of the message [Required] [ForeignKey("Sender")] [Display(Name = "Sender")] // [InverseProperty("MessageSenderId")] public string SenderId { get; set; } // ReceiverId of this message [Required] [ForeignKey("Receiver")] [Display(Name = "Receiver")] // [InverseProperty("MessageReceiverId")] public string ReceiverId { get; set; } // other properties }
- 3 open Package Manager Console and type the command
PM> Add-Migration ee1
- 4 find the 201802050240405_ee1.cs file from Migrations folder and change .ForeignKey("dbo.AspNetUsers", t => t.ReceiverId, cascadeDelete: true) to .ForeignKey("dbo.AspNetUsers", t => t.ReceiverId, cascadeDelete: false)
public partial class ee1 : DbMigration { public override void Up() { CreateTable( "dbo.Messages", c => new { Id = c.Int(nullable: false, identity: true), SenderId = c.String(nullable: false, maxLength: 128), ReceiverId = c.String(nullable: false, maxLength: 128), }) .PrimaryKey(t => t.Id) .ForeignKey("dbo.AspNetUsers", t => t.ReceiverId, cascadeDelete: false) .ForeignKey("dbo.AspNetUsers", t => t.SenderId, cascadeDelete: false) .Index(t => t.SenderId) .Index(t => t.ReceiverId); } ... }
- 5. Ok. Everything is right and we can view the picture;
Guide
With regards, Angelina Jolie
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, February 5, 2018 3:07 AM
All replies
-
User-832373396 posted
Hi Ehsan,
How to add 2 foreign keys and their corresponding navigation properties to a modelPlease change a bit to your current code, then it will work.
Here is the testing working example;
- 1 find the class ApplicationUser and add navigation properties ;
public class ApplicationUser : IdentityUser { public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, authenticationType); // Add custom user claims here return userIdentity; } [InverseProperty("Sender")] public virtual ICollection<Message> SenderMessages { get; set; } [InverseProperty("Receiver")] public virtual ICollection<Message> ReceiverMessages { get; set; } }
- 2 remove InverseProperty attribute to SenderId and ReceiverId
public class Message { [Key] public int Id { get; set; } // AspNetUsers public virtual ApplicationUser Sender { get; set; } public virtual ApplicationUser Receiver { get; set; } // SenderId of the message [Required] [ForeignKey("Sender")] [Display(Name = "Sender")] // [InverseProperty("MessageSenderId")] public string SenderId { get; set; } // ReceiverId of this message [Required] [ForeignKey("Receiver")] [Display(Name = "Receiver")] // [InverseProperty("MessageReceiverId")] public string ReceiverId { get; set; } // other properties }
- 3 open Package Manager Console and type the command
PM> Add-Migration ee1
- 4 find the 201802050240405_ee1.cs file from Migrations folder and change .ForeignKey("dbo.AspNetUsers", t => t.ReceiverId, cascadeDelete: true) to .ForeignKey("dbo.AspNetUsers", t => t.ReceiverId, cascadeDelete: false)
public partial class ee1 : DbMigration { public override void Up() { CreateTable( "dbo.Messages", c => new { Id = c.Int(nullable: false, identity: true), SenderId = c.String(nullable: false, maxLength: 128), ReceiverId = c.String(nullable: false, maxLength: 128), }) .PrimaryKey(t => t.Id) .ForeignKey("dbo.AspNetUsers", t => t.ReceiverId, cascadeDelete: false) .ForeignKey("dbo.AspNetUsers", t => t.SenderId, cascadeDelete: false) .Index(t => t.SenderId) .Index(t => t.ReceiverId); } ... }
- 5. Ok. Everything is right and we can view the picture;
Guide
With regards, Angelina Jolie
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, February 5, 2018 3:07 AM -
User-186068080 posted
Thanks AngelinaJoli for your complete answer.
But i come to another question. Since i never want to navigate back from user to his mail, does it impose extra load to server?
Wednesday, February 7, 2018 9:29 AM