it-swarm.dev

رمز إطار الكيان (EF) First Cascade (حذف تتالي) لعلاقة من شخص إلى صف واحد أو واحد

باتباع القسم "Code First Modelling" من الدورة التدريبية { Pluralsight "الشروع في العمل مع Entity Framework 5" من تأليف Julie Lerman ، قمتُ بإنشاء فئتي POCO مع واحد إلى صفر أو واحد العلاقة: أحد الوالدين (مستخدم) و اختياري طفل (UserDetail).

مخطط نموذج بيانات المستخدم و UserDetail (انقر للعرض).

لاحظ في الرسم التخطيطي أن الخاصية UserId هي مفتاح أساسي ومفتاح خارجي لـ UserDetail .

الكود ذو الصلة:

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();

        //...
    }
}

عندما يتم استدعاء الأسلوب Delete () في فئة UserRepository ، فإنه لا يحذف سجل المستخدم في قاعدة البيانات لأن المفتاح الخارجي في UserDetail لم يتم تمكين حذف المتتالية.

تتعارض عبارة DELETE مع قيد REFERENCE "FK_dbo.UserDetail_dbo.User_UserId".

كيف يمكنك تمكين الحذف المتتالي لـ العلاقات من واحد إلى الصفر أو واحد استخدام رمز إطار عمل الكيان أولاً (بحيث يؤدي حذف مستخدم إلى حذف UserDetail تلقائيًا)؟

51
arsenalogy

سوف تضطر إلى استخدام API بطلاقة للقيام بذلك.

حاول إضافة ما يلي إلى DbContext:

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

يمكنك أيضًا تعطيل اصطلاح الحذف المتتالي في النطاق العام للتطبيق الخاص بك عن طريق القيام بذلك:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()
3
rajeemcariazo

عملت هذا الرمز بالنسبة لي

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

رمز الترحيل هو:

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

وانها تعمل بشكل جيد. عندما كنت تستخدم لأول مرة

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

رمز الترحيل هو:

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

ولكنه لا يتطابق مع أي من الأحمال الزائدة المتوفرة (في EntityFramework 6)

1
Lupa