我正在使用由SQL Server 2012 express數據庫支持的Entity-Framework Core(版本號"EntityFramework.Core": "7.0.0-rc1-final"
)開發ASP.NET MVC 6項目。實體框架核心代碼 - 第一:在多對多關係上級聯刪除
我需要建模一個Person
實體和一個Address
實體之間的多對多關係。 根據this指南,我使用PersonAddress
連接表實體對其進行建模,因爲這樣我可以存儲一些額外的信息。
我目標是建立在我的系統是這樣的:
- 如果
Person
實例被刪除,所有相關PersonAddress
情況下,必須刪除。它們所引用的所有Address
實例必須也被刪除,前提是它們與其他PersonAddress
實例無關。 - 如果刪除
PersonAddress
實例,則必須刪除與其相關的Address
實例,只有當它與其他PersonAddress
實例無關。所有Person
實例都必須存在。 - 如果刪除了一個
Address
實例,則必須刪除所有相關的PersonAddress
實例。所有Person
實例都必須存在。
我想大多數的工作都必須在Person
和Address
之間的許多一對多的關係來完成的,但我希望能寫一些邏輯了。我將把這一部分擺脫這個問題。我感興趣的是如何配置我的多對多關係。
這是目前的情況。
這是Person
實體。請注意,此實體與其他輔助實體有一對多的關係。
public class Person
{
public int Id {get; set; } //PK
public virtual ICollection<Telephone> Telephones { get; set; } //navigation property
public virtual ICollection<PersonAddress> Addresses { get; set; } //navigation property for the many-to-many relationship
}
這是Address
實體。
public class Address
{
public int Id { get; set; } //PK
public int CityId { get; set; } //FK
public City City { get; set; } //navigation property
public virtual ICollection<PersonAddress> People { get; set; } //navigation property
}
這是PersonAddress
實體。
public class PersonAddress
{
//PK: PersonId + AddressId
public int PersonId { get; set; } //FK
public Person Person {get; set; } //navigation property
public int AddressId { get; set; } //FK
public Address Address {get; set; } //navigation property
//other info removed for simplicity
}
這是DatabaseContext
實體,其中描述了所有的關係。
public class DataBaseContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<Address> Addresses { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
//All the telephones must be deleteded alongside a Person.
//Deleting a telephone must not delete the person it refers to.
builder.Entity<Person>()
.HasMany(p => p.Telephones)
.WithOne(p => p.Person);
//I don't want to delete the City when I delete an Address
builder.Entity<Address>()
.HasOne(p => p.City)
.WithMany(p => p.Addresses)
.IsRequired().OnDelete(Microsoft.Data.Entity.Metadata.DeleteBehavior.Restrict);
//PK for the join entity
builder.Entity<PersonAddress>()
.HasKey(x => new { x.AddressId, x.PersonId });
builder.Entity<PersonAddress>()
.HasOne(p => p.Person)
.WithMany(p => p.Addresses)
.IsRequired();
builder.Entity<PersonAddress>()
.HasOne(p => p.Address)
.WithMany(p => p.People)
.IsRequired();
}
}
Telephone
都和City
實體已經爲簡單起見移除。
這是刪除Person
的代碼。
Person person = await _context.People.SingleAsync(m => m.Id == id);
try
{
_context.People.Remove(person);
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
}
至於我的讀數避免.Include()
會讓DB採取最終CASCADE
刪除的照顧。我很抱歉,但我不記得這個概念澄清的SO問題。
如果我運行這段代碼,我可以使用this workaround來播種數據庫。當我想測試,刪除Person
實體與上面的代碼,我得到這個異常:
The DELETE statement conflicted with the REFERENCE constraint "FK_PersonAddress_Person_PersonId". The conflict occurred in database "<dbName>", table "<dbo>.PersonAddress", column 'PersonId'.
The statement has been terminated.
我在DatabaseContext.OnModelCreating
方法測試了幾種關係設置沒有任何的運氣。
最後,這是我的問題。根據前面描述的目標,我應該如何配置我的多對多關係以正確地從我的應用程序中刪除Person
及其相關實體?
謝謝大家。