如何首先与Entity Framework代码创建多对多关系?

时间:2015-03-14 09:46:58

标签: c# entity-framework

尝试创建代码时,会显示以下错误:多对多关系。有人能告诉我出了什么问题吗?我到处搜索过,无法查看代码有什么问题。

介绍FOREIGN KEY约束' FK_dbo.BookingPeople_dbo.People_PersonID'在桌上' BookingPeople'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 无法创建约束或索引。查看以前的错误。

迁移:

        public override void Up()
    {
        CreateTable(
            "dbo.Bookings",
            c => new
                {
                    BookingID = c.Int(nullable: false),
                    startDate = c.DateTime(nullable: false),
                    endDate = c.DateTime(nullable: false),
                    Contact_PersonID = c.Int(nullable: false),
                    Type_BookingTypeID = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.BookingID)
            .ForeignKey("dbo.People", t => t.Contact_PersonID, cascadeDelete: true)
            .ForeignKey("dbo.BookingTypes", t => t.Type_BookingTypeID, cascadeDelete: true)
            .Index(t => t.Contact_PersonID)
            .Index(t => t.Type_BookingTypeID);

        CreateTable(
            "dbo.People",
            c => new
                {
                    PersonID = c.Int(nullable: false),
                    PersonAge = c.Int(nullable: false),
                    Type_PersonTypeID = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.PersonID)
            .ForeignKey("dbo.PersonTypes", t => t.Type_PersonTypeID, cascadeDelete: true)
            .Index(t => t.Type_PersonTypeID);

        CreateTable(
            "dbo.PersonTypes",
            c => new
                {
                    PersonTypeID = c.Int(nullable: false, identity: true),
                    Type = c.String(),
                })
            .PrimaryKey(t => t.PersonTypeID);

        CreateTable(
            "dbo.BookingTypes",
            c => new
                {
                    BookingTypeID = c.Int(nullable: false, identity: true),
                    Type = c.String(),
                })
            .PrimaryKey(t => t.BookingTypeID);

        CreateTable(
            "dbo.Users",
            c => new
                {
                    UserID = c.Int(nullable: false),
                    Username = c.String(maxLength: 30),
                    Password = c.String(unicode: false),
                })
            .PrimaryKey(t => t.UserID);

        CreateTable(
            "dbo.BookingPeople",
            c => new
                {
                    BookingID = c.Int(nullable: false),
                    PersonID = c.Int(nullable: false),
                })
            .PrimaryKey(t => new { t.BookingID, t.PersonID })
            .ForeignKey("dbo.Bookings", t => t.BookingID, cascadeDelete: true)
            .ForeignKey("dbo.People", t => t.PersonID, cascadeDelete: true)
            .Index(t => t.BookingID)
            .Index(t => t.PersonID);

    }

Fluent API代码:

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .Property(e => e.Password)
            .IsUnicode(false);

            modelBuilder.Entity<Booking>()
            .HasMany(t => t.People)
            .WithMany(t => t.Bookings)
            .Map(m =>
            {
                m.ToTable("BookingPeople");
                m.MapLeftKey("BookingID");
                m.MapRightKey("PersonID");
            });
    }

预订课程:

    public class Booking
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int BookingID { get; set; }

    [Required]
    public BookingType Type { get; set; }

    [Required]
    public Person Contact { get; set; }

    [Required]
    public DateTime startDate { get; set; }

    [Required]
    public DateTime endDate { get; set; }

    public virtual ICollection<Person> People { get; set; }

}

人员类:

    public class Person
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int PersonID { get; set; }

    [Required]
    public int PersonAge { get; set; }

    [Required]
    public PersonType Type { get; set; }

    public virtual ICollection<Booking> Bookings { get; set; }
}

更新了代码

迁移:

 public override void Up()
    {
        CreateTable(
            "dbo.Bookings",
            c => new
                {
                    BookingID = c.Int(nullable: false),
                    startDate = c.DateTime(nullable: false),
                    endDate = c.DateTime(nullable: false),
                    BookingType_BookingTypeID = c.Int(),
                })
            .PrimaryKey(t => t.BookingID)
            .ForeignKey("dbo.People", t => t.BookingID)
            .ForeignKey("dbo.BookingTypes", t => t.BookingType_BookingTypeID)
            .ForeignKey("dbo.BookingTypes", t => t.BookingID)
            .Index(t => t.BookingID)
            .Index(t => t.BookingType_BookingTypeID);

        CreateTable(
            "dbo.People",
            c => new
                {
                    PersonID = c.Int(nullable: false),
                    PersonAge = c.Int(nullable: false),
                    PersonType_PersonTypeID = c.Int(),
                })
            .PrimaryKey(t => t.PersonID)
            .ForeignKey("dbo.PersonTypes", t => t.PersonType_PersonTypeID)
            .ForeignKey("dbo.PersonTypes", t => t.PersonID)
            .Index(t => t.PersonID)
            .Index(t => t.PersonType_PersonTypeID);

        CreateTable(
            "dbo.PersonTypes",
            c => new
                {
                    PersonTypeID = c.Int(nullable: false, identity: true),
                    Type = c.String(),
                })
            .PrimaryKey(t => t.PersonTypeID);

        CreateTable(
            "dbo.BookingTypes",
            c => new
                {
                    BookingTypeID = c.Int(nullable: false, identity: true),
                    Type = c.String(),
                })
            .PrimaryKey(t => t.BookingTypeID);

        CreateTable(
            "dbo.Users",
            c => new
                {
                    UserID = c.Int(nullable: false, identity: true),
                    Username = c.String(maxLength: 30),
                    Password = c.String(unicode: false),
                })
            .PrimaryKey(t => t.UserID);

        CreateTable(
            "dbo.BookingPeople",
            c => new
                {
                    BookingID = c.Int(nullable: false),
                    PersonID = c.Int(nullable: false),
                })
            .PrimaryKey(t => new { t.BookingID, t.PersonID })
            .ForeignKey("dbo.Bookings", t => t.BookingID, cascadeDelete: true)
            .ForeignKey("dbo.People", t => t.PersonID, cascadeDelete: true)
            .Index(t => t.BookingID)
            .Index(t => t.PersonID);

    }

预订:

    public partial class Booking
{        
    public int BookingID { get; set; }


    public BookingType Type { get; set; }


    public Person Contact { get; set; }


    public DateTime startDate { get; set; }


    public DateTime endDate { get; set; }

    public virtual ICollection<Person> People { get; set; }

}

人:

    public partial class Person
{        
    public int PersonID { get; set; }

    public int PersonAge { get; set; }

    public PersonType Type { get; set; }

    public virtual ICollection<Booking> Bookings { get; set; }
}

Fluent API代码:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .Property(e => e.Password)
            .IsUnicode(false);

        // Booking
        // -------

        modelBuilder.Entity<Booking>()
        .HasRequired(b => b.Contact)
        .WithOptional()
        .WillCascadeOnDelete(false);

        modelBuilder.Entity<Booking>()
        .HasRequired(b => b.Type)
        .WithOptional()
        .WillCascadeOnDelete(false);

        modelBuilder.Entity<Booking>()
        .HasMany(t => t.People)
        .WithMany(t => t.Bookings)
        .Map(m =>
        {
            m.ToTable("BookingPeople");
            m.MapLeftKey("BookingID");
            m.MapRightKey("PersonID");
        });


        // Person
        // ------

        modelBuilder.Entity<Person>()
        .HasRequired(b => b.Type)
        .WithOptional()
        .WillCascadeOnDelete(false);


    }

更新代码:

迁移:

 public override void Up()
    {
        CreateTable(
            "dbo.Bookings",
            c => new
                {
                    BookingID = c.Int(nullable: false, identity: true),
                    startDate = c.DateTime(nullable: false),
                    endDate = c.DateTime(nullable: false),
                    Contact_PersonID = c.Int(nullable: false),
                    BookingType_BookingTypeID = c.Int(),
                    Type_BookingTypeID = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.BookingID)
            .ForeignKey("dbo.People", t => t.Contact_PersonID)
            .ForeignKey("dbo.BookingTypes", t => t.BookingType_BookingTypeID)
            .ForeignKey("dbo.BookingTypes", t => t.Type_BookingTypeID)
            .Index(t => t.Contact_PersonID)
            .Index(t => t.BookingType_BookingTypeID)
            .Index(t => t.Type_BookingTypeID);

        CreateTable(
            "dbo.People",
            c => new
                {
                    PersonID = c.Int(nullable: false, identity: true),
                    PersonAge = c.Int(nullable: false),
                    PersonType_PersonTypeID = c.Int(),
                    Type_PersonTypeID = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.PersonID)
            .ForeignKey("dbo.PersonTypes", t => t.PersonType_PersonTypeID)
            .ForeignKey("dbo.PersonTypes", t => t.Type_PersonTypeID)
            .Index(t => t.PersonType_PersonTypeID)
            .Index(t => t.Type_PersonTypeID);

        CreateTable(
            "dbo.PersonTypes",
            c => new
                {
                    PersonTypeID = c.Int(nullable: false, identity: true),
                    Type = c.String(),
                })
            .PrimaryKey(t => t.PersonTypeID);

        CreateTable(
            "dbo.BookingTypes",
            c => new
                {
                    BookingTypeID = c.Int(nullable: false, identity: true),
                    Type = c.String(),
                })
            .PrimaryKey(t => t.BookingTypeID);

        CreateTable(
            "dbo.Users",
            c => new
                {
                    UserID = c.Int(nullable: false, identity: true),
                    Username = c.String(maxLength: 30),
                    Password = c.String(unicode: false),
                })
            .PrimaryKey(t => t.UserID);

        CreateTable(
            "dbo.BookingPeople",
            c => new
                {
                    BookingID = c.Int(nullable: false),
                    PersonID = c.Int(nullable: false),
                })
            .PrimaryKey(t => new { t.BookingID, t.PersonID })
            .ForeignKey("dbo.Bookings", t => t.BookingID, cascadeDelete: true)
            .ForeignKey("dbo.People", t => t.PersonID, cascadeDelete: true)
            .Index(t => t.BookingID)
            .Index(t => t.PersonID);

    }

Fluent API代码:

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .Property(e => e.Password)
            .IsUnicode(false);

        // Booking
        // -------

        modelBuilder.Entity<Booking>()
        .HasRequired(b => b.Contact)
        .WithMany()
        .WillCascadeOnDelete(false);

         modelBuilder.Entity<Booking>()
        .HasRequired(b => b.Type)
        .WithMany()
        .WillCascadeOnDelete(false);

        modelBuilder.Entity<Booking>()
        .HasMany(t => t.People)
        .WithMany(t => t.Bookings)
        .Map(m =>
        {
            m.ToTable("BookingPeople");
            m.MapLeftKey("BookingID");
            m.MapRightKey("PersonID");
        });


        // Person
        // ------

        modelBuilder.Entity<Person>()
        .HasRequired(b => b.Type)
        .WithMany()
        .WillCascadeOnDelete(false);


    }

1 个答案:

答案 0 :(得分:2)

我认为这可能是问题

[Required]
public Person Contact { get; set; }

因为Required属性意味着级联删除由EF设置为true(例如,当您删除预订时,联系人(人)被删除但该人可能被另一个预订引用,因此错误消息

要修复删除所需属性并在FluentApi

中指定关系

在你的DbContext类

modelBuilder.Entity<Booking>()
            .HasRequired(b => b.Contact)
            .WithOptional()
            .WillCascadeOnDelete(false);