2016-08-29 7 views
0

私のアプリケーションには、ChemicalIdというプライマリキーを持つChemicalというクラスがあります。また、外部キーChemicalIdChemicalテーブルに結び付けられているクラスSampleLocationもあります。データベース/モデルを更新して、別のアイテムの外部キーがNULLになる行を削除する方法

I、データベースからChemicalを除去できるようにする必要がある(それを削除)することにより、nullに各SampleLocationChemicalIdの値を設定します。しかし、私は自分のアプリケーションでChemicalを削除しようとしたとき、私は次のエラーを取得:私のデータベースで

The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.SampleLocations_dbo.Chemicals_ChemicalId". The conflict occurred in database "aspnet-LIMS-20160112103244", table "dbo.SampleLocations", column 'ChemicalId'.

を、SampleLocationはヌルがOKですので、それに割り当てられている化学物質を「必要」が、もしいませんChemicalId列にIDがある場合は、有効なChemicalを参照する必要があります。

ChemicalIdの列タイプはint?です。したがって、NULLは許可されています。私のクラスには[required]という属性がないので、なぜこの削除を行えませんか?

OnModelCreatingメソッドを使って何かをする必要があることを私は知っていますが、私のアプリケーションにはそのようなメソッドはありません。どこでも見つけることができますそれはDbContextと呼ばれるクラスから継承しますが、私のアプリはそのようなクラス(私は一日ダウンした問い合わせ/ウサギの穴の全体の他のラインがある。)任意のアイデアを持っていませんか?

マイモデル:

1) SampleLocationクラス:

public class SampleLocation 
{ 
    [Key] 
    [Display(Name="Location ID")] 
    public int LocationId { get; set; } 

    [StringLength(35, ErrorMessage = "The Lease Name is limited to 35 characters")] 
    [Index("ix_uniqueSP", 1, IsUnique = true)] 
    [Display(Name = "Lease")] 
    public string LeaseName { get; set; } 

    [Required] 
    [StringLength(35, ErrorMessage = "The Well Number/Name is limited to 35 characters")] 
    [Index("ix_uniqueSP", 2, IsUnique = true)] 
    [Display(Name = "Well Name")] 
    public string WellNumber { get; set; } 

    //Foreign key 
    [Required] 
    [Index("ix_uniqueSP", 3, IsUnique = true)] 
    [Display(Name = "Customer")] 
    public int ClientId { get; set; } 
    [ForeignKey("ClientId")] 
    public virtual Company Companies { get; set; } 

    //Foreign key 
    [Required] 
    [Index("ix_uniqueSP", 4, IsUnique = true)] 
    [Display(Name = "District")] 
    public int DistrictId { get; set; } 
    [ForeignKey("DistrictId")] 
    public virtual District Districts { get; set; } 

    [Display(Name = "Foreman")] 
    public string ClientForeman { get; set; } 

    [Display(Name = "Zone")] 
    public string ClientZone { get; set; } 

    [Display(Name = "Run")] 
    public string ClientRun { get; set; } 

    [Display(Name = "API Number")] 
    [RegularExpression(@"^\d{14}|\d{2}-?\d{3}-?\d{5}-?\d{2}-?\d{2}$", ErrorMessage = "A valid 14 digit API number is required.")] 
    public string APINumber { get; set; } 

    [Display(Name = "Sample Point Name")] 
    public string SamplePointName 
    { 
     get { return LeaseName + " " + WellNumber; } 
    } 

    //Foreign key 
    [Display(Name = "Chemical")] 
    public int? ChemicalId { get; set; } 
    [ForeignKey("ChemicalId")] 
    public virtual Chemical Chemicals { get; set; } 
} 

2) IdentityModelsクラス:

public class ApplicationUser : IdentityUser 
{ 
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
    { 
     var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
     return userIdentity; 
    } 

    public static ApplicationUser Create() 
    { 
     return new ApplicationUser(); 
    } 

    public DbSet<ApplicationUser> AspNetUsers { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string InitialedName { get; set; } 
    public bool HasChangedPassword { get; set; } 

    //Foreign Key 
    public int Employer { get; set; } 
    [ForeignKey("Employer")] 
    public virtual Company Companies { get; set; } 
} 

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    public ApplicationDbContext() 
     : base("DefaultConnection", throwIfV1Schema: false) 
    { 
    } 

    public static ApplicationDbContext Create() 
    { 
     return new ApplicationDbContext(); 
    } 

    public DbSet<LabSample> LabSamples { get; set; } 
    public DbSet<SampleLocation> SampleLocations { get; set; } 
    public DbSet<Company> Companies { get; set; } 
    public DbSet<Chemical> Chemicals { get; set; } 
    public DbSet<LegitDomain> Domains { get; set; } 
    public DbSet<District> Districts { get; set; } 
    public DbSet<AccountManagerAssignment> AccountManagerAssignments { get; set; } 
} 

3)化学クラス:

public class Chemical 
{ 
    [Key] 
    public int ChemicalId { get; set; } 
    public string Name { get; set; } 
    public double ProductFactor { get; set; } 

    public virtual ICollection<SampleLocation> SampleLocations { get; set; } 
} 

ご協力いただければ幸いです。

答えて

1

あなたのケミカルテーブルからレコードを削除しようとしているとき、SampleLocationテーブル内の1つのまたは複数のレコードがまだそれを参照するため、このエラーを取得しています。

あなたは、まず削除したい化学物質レコードを参照するSampleLocationテーブルのすべてのレコードの値を変更する必要があります。これが完了し、SampleLocationのレコードがChemicalテーブルのレコードを参照していない場合は、それを削除することができます。

+0

ああ。だから、コントローラの私のdeleteメソッドでは、私が最初にChemicalIdがChemicalId列に存在するSampleLocationテーブル内のすべてのレコードの検索を行うことができ、かつ明示的にnullにそれらの値を設定し、その後、私の削除操作を続行します。私はそれがうまくいって、私が再び動くようにするべきだと思います。もし私がその種の "cascadingSetToNull"を行うことができれば、カスケード削除(削除する必要のないレコードを削除する)を行うようにデータベースを設定するのではなく、よりエレガントな方法がないと思います。影響を受けるレコードのパラメータ? – Greg

+0

私はカスケード削除を提案しませんが、はい、あなたは今、その要点を持っています。そのレコードを削除しようとすると、プライマリテーブルの元のレコードを参照する外部キーフィールドを持つことはできません。つまり、外来キーの制約が避けようとしているものです。 – Kevin

+0

私はコントローラのdeleteメソッドを修正しました。私はいくつかのルールを破っているように、まだ私に間違って感じるが、それは確かに動作します。ありがとうございました! – Greg

0

私のために働いたコードは以下の通りです。再びありがとう、ケビン。

// POST: LabData/ChemicalDelete/5 
    [Authorize(Roles = "canDeleteDbAdmin")] 
    [HttpPost, ActionName("ChemicalDelete")] 
    [ValidateAntiForgeryToken] 
    public ActionResult DeleteChemicalConfirmed(int id) 
    { 
     foreach (SampleLocation l in db.SampleLocations) 
     { 
      if (l.ChemicalId == id) 
      { 
       l.ChemicalId = null; 
       db.Entry(l).State = EntityState.Modified; 
      } 
     } 
     db.SaveChanges(); 
     Chemical c = db.Chemicals.Find(id); 
     db.Chemicals.Remove(c); 
     db.SaveChanges(); 
     return RedirectToAction("ChemicalList"); 
    } 
関連する問題