2014-12-23 25 views
14

Kullanıcı, İşveren, Adaylar ve İş, bir işveren birden fazla iş oluşturabilir ve her iş sadece bir işverene sahip olabilir, bir aday birçok iş için başvurabilir ve her iş birden çok uygulamalı üyeye sahip olabilir.FOREIGN KEY kısıtlaması, döngülere veya çoklu kaskat yollarına neden olabilir. Herhangi bir eylemi silme

Yani ilişki şu şekildedir:

enter image description here

ben bir işveren silerseniz, ilgili tüm işlerini silmek için gidiyor ve kullanıcı gelen bir anında, varlık çerçevesi kodu ilk yaklaşım kullanıyorum Ben aday silerseniz veritabanı ve bu kullanıcı silmek için gidiyor:

modelBuilder.Entity<Employer>() 
    .HasRequired(e => e.User) 
    .WithOptional(e => e.Employer).WillCascadeOnDelete(); 

//member is candidate 
modelBuilder.Entity<Member>() 
    .HasRequired(e => e.User) 
    .WithOptional(e => e.Member).WillCascadeOnDelete(); 

modelBuilder.Entity<Employer>() 
    .HasMany(a => a.Jobs) 
    .WithRequired(b => b.Employer) 
    .WillCascadeOnDelete(); 

Her şey kullanarak veritabanı adaylar ve iş arasında birçok ilişki birçok belirtmek ve güncelleme dışında çalışıyor "güncelleme veritabanı 'MemberJobMap' yabancı anahtar kısıtlaması masaya 'FK_dbo.MemberJobMap_dbo.Jobs_JobId' Tanıtımı

döngüleri veya çoklu kaskad yolları neden olabilir:", bana bu hata veriyor. EYLEM YAPMAK ÜZERİNDE AÇIK veya EYLEM OLMADAN AÇIKLAMAK seçin veya diğer ÖNSÖZ ANAHTAR kısıtlamalarını değiştirin. Kısıtlama oluşturulamadı. Önceki hataları görün. İşte

Ben birçok ilişki birçok belirtilmiş nasıl:

modelBuilder.Entity<Member>() 
    .HasMany(m => m.Jobs) 
    .WithMany(j => j.Members) 
    .Map(c => 
    { 
     c.MapLeftKey("Id"); 
     c.MapRightKey("JobId"); 
     c.ToTable("MemberJobMap"); 
    }); 

ve ben göçü eklediğinizde:

CreateTable(
    "dbo.MemberJobMap", 
    c => new 
    { 
     Id = c.String(nullable: false, maxLength: 128), 
     JobId = c.Int(nullable: false), 
    }) 
    .PrimaryKey(t => new { t.Id, t.JobId }) 
    .ForeignKey("dbo.Members", t => t.Id, cascadeDelete: true) 
    .ForeignKey("dbo.Jobs", t => t.JobId, cascadeDelete: true) 
    .Index(t => t.Id) 
    .Index(t => t.JobId); 
Ben false cascadeDelete değiştirmeyi denedim

ama sildiğinizde o bana hata veriyor iş başvurusu yapan veya başvurulan adaylarla bir işi silmeye çalıştığımda aday.

Bu hata nasıl giderilir? Böylece:

Bir iş kaldırılır
  1. , bu, ilişkili candidatejobmap tablo satırları kaldırmak için gidiyor başka bir tablo aday kaldırılır
  2. etkilemeksizin ilişkili candidatejobmap tablo satırları kaldırmak için gidiyor ve herhangi diğer tablo
  3. etkilemeksizin kullanıcı tablo satırı diğer tüm belirtilmiş kaskad eylemi silmek tutarken aynı ben i tasarlamak istiyorum

cevap

11

Bu sorunu iki basamaklı CandidateJobMap masaya yolunu silmek zorunda çünkü sorun oluşur

sabit

işveren> is how> CandidateJobMap

Ben aday silerseniz

, onun dele edecek: açmak CandidateJobMap tabloyu silmek te CandidateJobMap tablosu:

Üye-> CandidateJobMap

Yani bu sorunu aşmanın, ben silme yolunun bir, size birçok ilişkilere pek yaratıyor WillCascadeDelete (false) belirleyemezsiniz devre dışı bırakmak zorunda, bu yüzden

CreateTable(
    "dbo.MemberJobMap", 
    c => new 
    { 
     Id = c.String(nullable: false, maxLength: 128), 
     JobId = c.Int(nullable: false), 
    }) 
    .PrimaryKey(t => new { t.Id, t.JobId }) 
    .ForeignKey("dbo.Members", t => t.Id, cascadeDelete: false) <--------cascade delete to false 
    .ForeignKey("dbo.Jobs", t => t.JobId, cascadeDelete: true) 
    .Index(t => t.Id) 
    .Index(t => t.JobId); 

Eğer kaskad false silmek ayarlamak çünkü çalıştığınızda, bu başka hataya neden olur aday silinmiş olduğunda, bu ilgili CandidateJobMap satırları silmez Şimdi: yerine aşağıdaki gibi göç değiştirmek zorunda CandidateJobMap'de ilgili bir anahtarın olduğu bir adayı silebilirsiniz, böylece r'yi elle silmeniz gerekir adayı çıkarmadan önce CandidateJobMap içinde mutlu satırlar:

//remove all applied jobs from user, without doing this, you will receive an error 
foreach (var appliedjob in user.Member.Jobs.ToList()) 
{ 
    user.Member.Jobs.Remove(appliedjob); 
} 

//before you can delete the user 
await UserManager.DeleteAsync(user); 

bu en iyi yoldur, ama bu benim için çalıştı emin değilim.

+0

sorunu gizlediniz, çağlayan silme, birleştirme tablosunun her iki tarafından da çalışmalıdır. Bu, ER M'deki bir hata gibi kokmuyor ya da kullandığınız şekilde bir hata yapıyor. – Jasen

+0

@Jasen kaskad benim için çalışmıyor Her iki taraftan silmek çünkü bana ben – Mindless

+1

Evet, tek bir çok-çok" varlık ile daha basit kurulum var sorulan hata veriyor, açıklamak ve ne zaman aynı hatayı alıyorum Lütfen Birden çok ilişkiyi aynı anda çağlayanı silme işlemini etkinleştirmeye çalışıyorum, bunun sadece bir SQL Server sınırlaması olduğunu düşünüyorum. –

2

Böyle bir şey ..Ben işvereni silerseniz

, onun hangi irade, ilgili işveren işlerini silmek için gidiyor:

User_Type <-- Tow types of users Candidates and Employers  


USERS  <-- Common Fields for Candidates and Employers , along with one column to 
      -- identify if it is Candidate or an Employer referencing back to User_Type 

Emp_Details <-- Only columns that an employer will have referencing back to Users table 

Can_Details <-- Only columns that a Candidate will have referencing back to Users table 

Jobs   <-- Jobs published by a user who is an employer referencing back to Users table 

CandidateJobs <-- A composite key referencing back to Jobs(JobId) and Users who are 
       --Candidates 
+0

sayesinde Bulunduğum ilişki önerdiğiniz biri Empolyer ve Candadidates temel Emp_Details ve Can_Details tablo vardır çok benzer, ben rolleri tablo tanımlı var ama Ben bahsetmedim çünkü bu soru ile alakasız olduğunu düşünüyorum, ben adaylar ve İşveren hem farklı ilişkiler ile aynı İşler tablosuna başvurmak isterdim (bir çok ve çok çok). – Mindless

3

Bunun oldukça eski olduğunu anlıyorum ama aynı konuyla karşılaştım ve ele alınmayan bazı yorumlar var.

Özellikle çoklu yollardan

Cascade "Eğer ... Sorunu gizlediğiniz" gerektiği eser o da atası silme soyundan silme etkiye sahip olmasıdır geçerli olduğu için. Ancak bu sadece teoride, gerçekte SQL Server buna izin vermez, dolayısıyla hataya neden olmaz. Bu yazının bir çözümü burada solving-the-sql-server-multiple-cascade-path-issue-with-a-trigger.

O, tüm kusurlu kaskad eylemlerin çıkarılmasını önerir ve kayıtları silmek için tetikleyiciler ile hepsini yerine. Kaskad zincirinin en üst seviyesinde çalışmayı tercih ederim. Onun örnekte ben sadece YERİNE çocuklar için SİL ile 'ebeveyn' kayıt adresten kesti ve kaskad dinlenme dikkat izin verirdi.

iki nedenden

için bunu
  1. kötü veriler için son savunma hattı, çünkü o tür giysiler gitmek hemen önce cepleri boşaltmak gibi ... veritabanında yapılmalı yıkayıcı. şeylerin bakımı ileride bu bir DB kapalı inşa olabilecek tüm farklı modellere kod çoğaltmak zorunda, ne sen ona bakmak için tüm acemi devs saymak zorunda yapmayın orada anlamına gelir. üstteki atası de yapıyor

  2. diğer tüm ilişkiler ileride ekleyebiliriz de dahil kalmasını sağlayacaktır.Bu yardımcı olur

Umut, Mike yanıt

İlgili konular