2012-04-04 61 views
3

我有一個實體,包括許多不同的文檔與我的數據庫中的任何實體unkown關係。與OneWay的一對一或零關係CascadeOnDelete

public class Document : BaseEntity 
{ 

    public string Filename { get; set; } 

    public string MIMEType { get; set; } 
    public int? Length { get; set; } 

    public byte[] Content { get; set; } 

} 

和codefirst映射是:

public DocumentConfiguration() 
    { 
     Property(x => x.Filename).HasMaxLength(300).IsRequired(); 
     Property(x => x.MIMEType).HasMaxLength(300).IsRequired(); 
     Property(x => x.Length).IsOptional(); 
     Property(x => x.Content).IsOptional().HasColumnType("varbinary(max)"); 


     ToTable("Document"); 
    } 

現在我想一個可選的關係記錄表在我addressentity像這樣:

public class Address : BaseEntity 
{ 

    public string Name1 { get; set; } 
    public string Name2 { get; set; } 
    public string Additional { get; set; } 


    public string Street { get; set; } 
    public string HousNr { get; set; } 
    public string ZipCode { get; set; } 
    public string City { get; set; } 

    public virtual Document Image { get; set; } 

} 

與以下映射:

public AddressConfiguration() 
    { 

     Property(x => x.Name1).IsRequired().HasMaxLength(250); 
     Property(x => x.Name2).HasMaxLength(250); 
     Property(x => x.Additional).HasMaxLength(250); 


     Property(x => x.Street).HasMaxLength(250); 
     Property(x => x.HousNr).HasMaxLength(10); 
     Property(x => x.ZipCode).HasMaxLength(10); 
     Property(x => x.City).HasMaxLength(100); 


     HasOptional(x => x.Image) 
      .WithOptionalDependent() 
      .Map(map => map.MapKey("ImageId")).WillCascadeOnDelete(); 


     ToTable("Address"); 

    } 

但是,在刪除文檔表中的圖像時刪除相關地址。

我想要一個OneWay-Deletation從地址到文檔,但不是從文檔到地址...?

我該如何實現?

謝謝。

回答

5

它已經從文件到地址級聯的原因是因爲你用WithOptionalDependent方法。從文檔:

將關係配置爲可選:在關係的另一側沒有導航屬性可選。正在配置的實體類型將是依賴項,並且包含主體的外鍵。關係所針對的實體類型將成爲關係中的主體。

考慮AddressConfiguration方法這行代碼:

HasOptional(x => x.Image)   // The entity type being configured is Address 
    .WithOptionalDependent()... // The entity type that the relationship targets 
           // is Document (x.Image) 

,意味着你指定地址的依賴性和文檔作爲該協會因此級聯行爲的主體。

但是等等,這個故事還有更多!您可以通過兩種方式創建一對一關聯。首先是共享主鍵協會一對一外鍵協會。您可以從herehere瞭解更多關於它們的信息。看起來你想通過一個外鍵(一對一外鍵關聯)映射你的關聯。如果是這樣,你必須注意,依賴實體將始終攜帶外鍵,這意味着你的情況下,文檔實體將有一個AddressId引用地址實體上的AddressId(你做了相反的事情是不正確的)。

之所以這麼說,你的對象模型和流利的API代碼應該是這樣的:

public class Address 
{ 
    public int AddressId { get; set; } 
    public virtual Document Image { get; set; } 
} 

public class Document 
{ 
    public int DocumentId { get; set; } 
} 

class Context : DbContext 
{ 
    public DbSet<Address> Addresses { get; set; } 
    public DbSet<Document> Documents { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Address>() // The entity being configured is Address 
        .HasOptional(x => x.Image) 
        .WithOptionalPrincipal() 
        .Map(map => map.MapKey("AddressId")) 
        .WillCascadeOnDelete(); 
    } 
} 

基本上WithOptionalPrincipal是方法,你應該使用:

配置的關係是可選的:在關係的另一側沒有導航屬性可選。正在配置的實體類型將成爲關係中的主體。關係所針對的實體類型將是依賴關係,並且包含對主體的外鍵。


結果級聯刪除正確的地址,從開機到文檔中。

+0

謝謝morteza。文檔可以從各種實體中引用,所以我可以爲所有即將到來的實體映射相同的指定「外鍵」 :「RelatedRecordId」與任何類型的關係(一對一或一對多..?可選我可以有一個沒有任何關係的文檔.. – 2012-04-06 09:18:32

+0

不,你不能!AddressId只用於地址和地址。不支持FK引用多個實體,EF也不支持。你必須在文檔上有更多的FK,這不一定是一個好的設計。也許你可以回到你的源頭最終通過在地址上提供DocId來設計,但爲什麼您需要Cascades?如果共享文檔,刪除地址不應刪除其相關文檔,因爲它可能會被其他實體引用。 – 2012-04-06 14:05:48

+0

但是,如果我想要從任何實體到​​文檔實體的一對多關係?我怎麼能映射?謝謝。 – 2012-04-10 07:17:40

0

嘗試刪除OneToManyCascadeDeleteConvention:modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention >();

+0

dataschema代沒有變化! :-(在刪除管理工作室中的相關文檔後,sql-server也刪除相關地址! – 2012-04-04 14:04:57

+0

但是也存在fk從文檔到地址? – ADIMO 2012-04-04 14:11:52

+0

我有一個帶級聯刪除的FK_Address_Document_ImageId ... – 2012-04-04 15:34:19