介绍FOREIGN KEY约束 - 数据库设置

时间:2013-07-24 12:33:49

标签: sql-server entity-framework asp.net-mvc-4 database-design foreign-keys

有一段时间我一直在研究和阅读如何解决我的问题,甚至认为我找到了类似的问题,没有任何明确的答案,我尝试的一切似乎都没有用。我对ASP.NET MVC4有点熟悉(我的主要能力依赖于PHP和MySQL)。出于学习目的,我决定开展一个小项目以增强我的C#noobie知识,但我遇到了一个小问题,我感觉它可能很容易,而且有一些我不记得的东西,但我如果您向我提供以下内容的想法或解决方案,我将非常感激:

我创建了以下模型:

public class Address
{
    [Key]
    public int AddId { get; set; }
    public int HouseNo { get; set; }
    public string AddLine1 { get; set; }
    public string AddLine2 { get; set; }
    public string City { get; set; }
    public string PostCode { get; set; }
    //public ICollection<GpModel> GpList { get; set; }
    //public ICollection<PharmacyModel> PharmacyList { get; set; }
}

public class GpModel
{
    [Key]
    public int GpId { get; set; }
    public int AddId { get; set; }
    public string GpName { get; set; }
    public Int64 GpTelephone { get; set; }

    [ForeignKey("AddId")]
    public virtual Address GpAddress { get; set; }
    public ICollection<GpnPharmacy> GpnPharmacies { get; set; }
}

public class PharmacyModel
{
    [Key]
    public int PharmacyId { get; set; }
    public int AddId { get; set; }
    public string PharmacyName { get; set; }
    public Int64 PharmacyTelephone { get; set; }

    [ForeignKey("AddId")]
    public virtual Address PharmacyAddress { get; set; }
    public ICollection<GpnPharmacy> GpnPharmacies { get; set; }
}

public class GpnPharmacy
{
    [Key]
    public int GpnPharId { get; set; }
    public int GpId { get; set; }
    public int PharmacyId { get; set; }

    //[ForeignKey("GpId")]
    public virtual GpModel Gp { get; set; }

    //[ForeignKey("PharmacyId")]
    public virtual PharmacyModel Pharmacy { get; set; }
}

public class MyScriptV1Entities : DbContext
{
    public DbSet<Address> Addresses { get; set; }
    public DbSet<GpModel> Gps { get; set; }
    public DbSet<PharmacyModel> Pharmacies { get; set; }
    public DbSet<GpnPharmacy> GpnPharmacies { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<GpModel>()
            .HasRequired(s => s.GpAddress)
            .WithMany()
            .WillCascadeOnDelete(true);

        modelBuilder.Entity<PharmacyModel>()
            .HasRequired(s => s.PharmacyAddress)
            .WithMany()
            .WillCascadeOnDelete(true);

        base.OnModelCreating(modelBuilder);
    }
}

关系如下:

  • 每个GpModel和PharmacyModel都有一个地址。
  • PharmacyModel将“注册”为0或更多GpModel
  • GpModel将在其名称
  • 下有0个或更多PharmacyModel“已注册”

基本上我试图在PharmacyGp之间建立多对多的关系,为此,我认为创建一个单独的表GpnPharmacy会保留其ID和基本上“联系”他们。

但是我认为我的问题依赖于我的模型构建器(我可能错了)但我似乎无法使用我在网上找到的东西解决它。

当我在GpController上启动以下操作时(使用/Gp/Details/1

public ActionResult Details(int id)
    {
        var GpModel = MySciptV1DB.Gps.Find(id);
        return View(GpModel);

    }

我没有从数据库中获取第一个Gp详细信息,而是收到以下错误:

  

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

我应该提一下,我的应用程序首先使用SampleData.cs文件中的数据填充数据库。由于某种原因,尚未创建表格。

如果您需要更多信息,请随时提出问题,如果我不够清楚,我会道歉,但我对ASP.NET上的SQL有些新意。非常感谢你的时间。

问候。

1 个答案:

答案 0 :(得分:0)

我认为尝试将下面的内容更改为false。

.WillCascadeOnDelete(true);

这是创建多个删除级联路径,因为删除地址可能同时删除GP和Pharma,这反过来可能会导致级联删除GpnPharmacy表的问题。

如果需要级联,您应该手动处理删除(例如,通过存储过程来检查是否可以安全地删除内容然后从所有相关表中删除)。