locked
Asp.Net MVC Data Modeling RRS feed

  • Question

  • I have a problem with asp.net mvc data modeling. I have to model class called `User` and `Conversation`.

    User.cs

    public class User
        {
            public User()
            {
            }
    
            [Key]
            [Required]
            [DataType(DataType.EmailAddress)]
            [StringLength(50, ErrorMessage = "User name must be less than 50 characters.")]
            [Display(Name = "User name")]
            public string UserName { get; set; }
    
            [Required]
            [DataType(DataType.Text)]
            [StringLength(50, ErrorMessage = "Name must be less than 50 characters.")]
            [Display(Name = "Name")]
            public string Name { get; set; }
    
            [Required]
            [DataType(DataType.DateTime)]
            [Display(Name = "Birthdate")]
            public string Birthdate { get; set; }
    
            [Required]
            [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
            [DataType(DataType.Password)]
            [Display(Name = "Password")]
            public string Password { get; set; }
    
            [DataType(DataType.Password)]
            [Display(Name = "Confirm password")]
            [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
            public string ConfirmPassword { get; set; }
    
            [DataType(DataType.DateTime)]
            public DateTime created_at { get; set; }
    }

    and

    Conversation.cs

    public class Conversation
        {
            public Conversation()
            {
                status = messageStatus.Sent;
            }
    
            public enum messageStatus
            {
                Sent,
                Delivered
            }
    
            [Key, ForeignKey("SenderUser"), Column(Order = 1)]
            [Required]
            [DataType(DataType.EmailAddress)]
            public string SenderUserName { get; set; }
            public virtual User SenderUser { get; set; }
    
            [Key, ForeignKey("ReceiverUser"), Column(Order = 2)]
            [Required]
            [DataType(DataType.EmailAddress)]
            public string ReceiverUserName { get; set; }
            public virtual User ReceiverUser { get; set; }
    
            [Key, Column(Order = 3)]
            [DataType(DataType.DateTime)]
            public DateTime created_at { get; set; }
    
            [Required]
            [DataType(DataType.MultilineText)]
            public string message { get; set; }
    
            public messageStatus status { get; set; }
        }

    and my ChatContext is like this:

    public class ChatContext : DbContext
        {
            public ChatContext() : base("DefaultConnection")
            {
            }
    
            public static ChatContext Create()
            {
                return new ChatContext();
            }
    
            public DbSet<User> Users { get; set; }
            public DbSet<Conversation> Conversations { get; set; }
        }

    When I run my asp app, I get this error:

    Introducing FOREIGN KEY constraint 'FK_dbo.Conversations_dbo.Users_SenderUserName' on table 'Conversations' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
    Could not create constraint or index. See previous errors.

    What's wrong with my design?


    • Edited by M_Deh Friday, May 18, 2018 3:28 PM
    • Moved by CoolDadTx Monday, May 21, 2018 2:56 PM EF related
    Friday, May 18, 2018 3:08 PM

All replies

  • You can get better support at the EF forum, becuase that's what you are dealing with is EF Code First approach.

    http://social.msdn.microsoft.com/Forums/en-US/home?forum=adodotnetentityframework

    Friday, May 18, 2018 6:57 PM
  • Hi M_Deh,

    Based on your description, I create a simple sample and reproduce the issue on my side, it is a by design issue, please modify your Migrations file and change the first one cascadeDelete to false. it will works well.

    namespace ConsoleApp24.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;
        
        public partial class _base : DbMigration
        {
            public override void Up()
            {
                CreateTable(
                    "dbo.Conversations",
                    c => new
                        {
                            SenderUserName = c.String(nullable: false, maxLength: 50),
                            ReceiverUserName = c.String(nullable: false, maxLength: 50),
                            created_at = c.DateTime(nullable: false),
                            message = c.String(nullable: false),
                            status = c.Int(nullable: false),
                        })
                    .PrimaryKey(t => new { t.SenderUserName, t.ReceiverUserName, t.created_at })
                    .ForeignKey("dbo.Users", t => t.ReceiverUserName, cascadeDelete: false)
                    .ForeignKey("dbo.Users", t => t.SenderUserName, cascadeDelete: true)
                    .Index(t => t.SenderUserName)
                    .Index(t => t.ReceiverUserName);
                
                CreateTable(
                    "dbo.Users",
                    c => new
                        {
                            UserName = c.String(nullable: false, maxLength: 50),
                            Name = c.String(nullable: false, maxLength: 50),
                            Birthdate = c.String(nullable: false),
                            Password = c.String(nullable: false, maxLength: 100),
                            ConfirmPassword = c.String(),
                            created_at = c.DateTime(nullable: false),
                        })
                    .PrimaryKey(t => t.UserName);
                
            }
            
            public override void Down()
            {
                DropForeignKey("dbo.Conversations", "SenderUserName", "dbo.Users");
                DropForeignKey("dbo.Conversations", "ReceiverUserName", "dbo.Users");
                DropIndex("dbo.Conversations", new[] { "ReceiverUserName" });
                DropIndex("dbo.Conversations", new[] { "SenderUserName" });
                DropTable("dbo.Users");
                DropTable("dbo.Conversations");
            }
        }
    }
    

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, May 24, 2018 5:35 AM