【问题标题】:Cascading delete on a Entity Framework Child that requires Either Parents but not both在需要父级但不是两者的实体框架子级上级联删除
【发布时间】:2018-07-20 18:48:40
【问题描述】:

我有两个类与孩子有一对多的关系。孩子只能有一个父母,不能同时有两个。

我怎样才能做到这一点?如果是这样,如果任一父级被删除,我怎样才能使其级联删除?

class Parent1
{
    public int Id {get;set;}
    public IList<Child> Children {get;set;}
}

class Parent2
{
    public int Id {get;set;}    
    public IList<Child> Children {get;set;}
}

class Child
{
    public int Id {get;set;}
    public int? Parent1Id {get;set;}
    public int? Parent2Id {get;set;}
}

【问题讨论】:

    标签: entity-framework entity-framework-6 ef-code-first code-first


    【解决方案1】:

    您可以在 EF 中设置一个实体验证来检查这一点,但您还需要在数据库中创建一个 CHECK CONSTRAINT 以确保该规则得到实际执行。

    此外,您必须在子实体上同时具有 FK 属性和导航属性才能通过 EF 强制执行此操作。在新的 Child 上,Navigation 属性可以为非 null,但尚未填充 FK 属性。在现有实体上,将加载 FK 属性,但可能不会加载导航属性。 EG

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Data.Entity.Validation;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ef62test
    {
        class Program
        {
    
            public class Parent1
            {
                public int Id { get; set; }
                public virtual ICollection<Child> Children { get; } = new HashSet<Child>();
            }
    
            public class Parent2
            {
                public int Id { get; set; }
                public virtual ICollection<Child> Children { get;  } = new HashSet<Child>();
            }
    
            public class Child
            {
                public int Id { get; set; }
                public int? Parent1Id { get; set; }
                public virtual Parent1 Parent1 { get; set; }
    
                public int? Parent2Id { get; set; }
                public virtual Parent2 Parent2 { get; set; }
    
    
            }
    
    
            public class MyDbContext : DbContext
            {
    
                public DbSet<Parent1> Parent1s { get; set; }
    
                public DbSet<Parent2> Parent2s { get; set; }
    
                public DbSet<Child> Children { get; set; }
    
                protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
                {
                    var errors = new List<DbValidationError>();
                    if (entityEntry.Entity is Child child )
                    {
                        if ((child.Parent1Id != null || child.Parent1 != null) 
                              && (child.Parent2Id != null || child.Parent2 != null))
                        {
                            var error = new DbValidationError("Parent2id", "Parent2id must be null when Parent1id is null");
                            errors.Add(error);
                        }
    
                    }
    
                    return new DbEntityValidationResult(entityEntry, errors);
                }
    
                protected override void OnModelCreating(DbModelBuilder modelBuilder)
                {
    
    
                    base.OnModelCreating(modelBuilder);
                }
            }
            static void Main(string[] args)
            {
                Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());
    
                using (var db = new MyDbContext())
                {
                    db.Database.Log = s => Console.WriteLine(s);
    
                    var p1 = new Parent1();
                    var p2 = new Parent2();
                    var c = new Child();
                    p1.Children.Add(c);
                    p2.Children.Add(c);
    
                    db.Parent1s.Add(p1);
                    db.Parent2s.Add(p2);
                    db.Children.Add(c);
    
    
                    db.SaveChanges();
                }
    
    
                Console.WriteLine("Hit any key to exit.");
                Console.ReadKey();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多