48

Theo phần "Mã đầu tiên mô hình hóa" của Pluralsight "Getting Started with Entity Framework 5" course by Julie Lerman, tôi đã tạo hai lớp POCO với một số một hoặc không -one mối quan hệ: cha/mẹ (Người dùng) và tùy chọn trẻ em (UserDetail).Cấu trúc khung thực thể (EF) Đoạn đầu tiên cho mối quan hệ một hoặc không một

User and UserDetail data model diagram (click to view).

Lưu ý trong sơ đồ mà tài sản UserId là một khóa chính và khóa ngoại cho UserDetail.

đang liên quan:

public class User 
{ 
    //... 

    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int UserId { get; set; } 

    /* Has a 1:0..1 relationship with UserDetail */ 
    public virtual UserDetail UserDetail { get; set; } 

    //... 
} 

public class UserDetail 
{ 
    //... 

    /* Has a 0..1:1 relationship with User */ 
    public virtual User User { get; set; } 

    [Key, ForeignKey("User")] 
    public int UserId { get; set; } 

    //... 
} 

public class EFDbContext : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
    //public DbSet<UserDetail> UserDetails { get; set; } /* Explicit declaration not necessary. Context is aware of UserDetail entity due to 0..1:1 relationship with User */ 

    public EFDbContext() 
    { 
     Configuration.ProxyCreationEnabled = true; 
     Configuration.LazyLoadingEnabled = true; 
    } 
} 

public class UserRepository : IUserRepository 
{ 
    private EFDbContext _context = new EFDbContext(); 

    public void Delete(User entity) 
    { 
     entity = _context.Users.Find(entity.UserId); 

     //... 

     _context.Users.Remove(entity); 
     _context.SaveChanges(); 

     //... 
    } 
} 

Khi phương thức Delete() trong lớp UserRepository được gọi, nó không xóa hồ sơ người dùng trong cơ sở dữ liệu bởi vì chìa khóa nước ngoài tại UserDetail không có cascade delete được kích hoạt.

Tuyên bố DELETE xung đột với ràng buộc REFERENCE "FK_dbo.UserDetail_dbo.User_UserId".

Làm thế nào bạn sẽ cho phép tầng xóa cho one-to-zero-hay-một mối quan hệ sử dụng Entity Framework Mã đầu tiên (để xóa một tài khoản tự động xóa UserDetail)?

Trả lời

65

Bạn sẽ phải sử dụng API thông thạo để thực hiện việc này.

Hãy thử thêm dòng sau vào DbContext của bạn:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<User>() 
     .HasOptional(a => a.UserDetail) 
     .WithOptionalDependent() 
     .WillCascadeOnDelete(true); 
} 
+0

Các WillCascadeOnDelete() là những gì đã làm nó , mặc dù tôi đã phải áp dụng nó trên bảng phụ thuộc (UserDetail), không phải là hiệu trưởng (User) trong mối quan hệ này. Ngoài ra, tôi đã loại bỏ các khóa dữ liệu Key và ForeignKey trên thuộc tính UserId trong lớp UserDetail. Cảm ơn bạn rất nhiều! – arsenalogy

+5

FWIW, bài viết này đã giúp tôi có được ý tưởng áp dụng các WillCascadeOnDelete() vào bảng phụ thuộc http://msdn.microsoft.com/en-us/data/jj591620.aspx#RequiredToOptional. – arsenalogy

+5

Chính xác những gì tôi cần. Một số đã đề xuất [Bắt buộc] để xóa tầng. Điều này thực sự hoạt động, nhưng tất nhiên, chỉ khi nó thực sự là cần thiết. – CodeMonkey

0

Mã này làm việc cho tôi

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<UserDetail>() 
      .HasRequired(d => d.User) 
      .WithOptional(u => u.UserDetail) 
      .WillCascadeOnDelete(true); 
    } 

Mã di cư là:

public override void Up() 
    { 
     AddForeignKey("UserDetail", "UserId", "User", "UserId", cascadeDelete: true); 
    } 

Và nó làm việc tốt. Khi tôi lần đầu tiên sử dụng

modelBuilder.Entity<User>() 
    .HasOptional(a => a.UserDetail) 
    .WithOptionalDependent() 
    .WillCascadeOnDelete(true); 

Mã di cư là:

AddForeignKey("User", "UserDetail_UserId", "UserDetail", "UserId", cascadeDelete: true); 

nhưng nó không phù hợp với bất kỳ của hai định nghĩa chồng có sẵn (trong EntityFramework 6)

Các vấn đề liên quan