Entity framework 在实体框架子级上级联删除,该子级需要父级中的一个,但不需要父级和父级

Entity framework 在实体框架子级上级联删除,该子级需要父级中的一个,但不需要父级和父级,entity-framework,entity-framework-6,ef-code-first,code-first,Entity Framework,Entity Framework 6,Ef Code First,Code First,我有两个与孩子有一对多关系的班级。孩子只能有一个父母,不能同时有两个 我怎样才能做到这一点?如果是这样的话,如果父母中的任何一方被删除了,我怎么能让它级联删除呢 class Parent1 { public int Id {get;set;} public IList<Child> Children {get;set;} } class Parent2 { public int Id {get;set;} public IList<Ch

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

我怎样才能做到这一点?如果是这样的话,如果父母中的任何一方被删除了,我怎么能让它级联删除呢

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;}
}
class-Parent1
{
公共int Id{get;set;}
公共IList子项{get;set;}
}
班级家长2
{
公共int Id{get;set;}
公共IList子项{get;set;}
}
班童
{
公共int Id{get;set;}
public int?Parent1Id{get;set;}
公共int?Parent2Id{get;set;}
}

您可以在EF中设置实体验证来检查此项,但还需要在数据库中创建检查约束,以确保实际执行该规则

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

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();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.ComponentModel.DataAnnotations;
使用System.ComponentModel.DataAnnotations.Schema;
使用System.Data.Entity;
使用System.Data.Entity.Infrastructure;
使用System.Data.Entity.Validation;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间ef62test
{
班级计划
{
公共类家长1
{
公共int Id{get;set;}
公共虚拟ICollection子项{get;}=new HashSet();
}
公共类家长2
{
公共int Id{get;set;}
公共虚拟ICollection子项{get;}=new HashSet();
}
公营儿童
{
公共int Id{get;set;}
public int?Parent1Id{get;set;}
公共虚拟Parent1 Parent1{get;set;}
公共int?Parent2Id{get;set;}
公共虚拟Parent2 Parent2{get;set;}
}
公共类MyDbContext:DbContext
{
公共数据库集Parent1s{get;set;}
公共DbSet Parent2s{get;set;}
公共DbSet子项{get;set;}
受保护的重写DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry,IDictionary项)
{
var errors=新列表();
if(entityEntry.Entity为子项)
{
if((child.Parent1Id!=null | | child.Parent1!=null)
&&(child.Parent2Id!=null | | child.Parent2!=null))
{
var error=new DbValidationError(“Parent2id”,“Parent1id为null时Parent2id必须为null”);
错误。添加(错误);
}
}
返回新的DbEntityValidationResult(entityEntry,错误);
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
}
}
静态void Main(字符串[]参数)
{
SetInitializer(新的DropCreateDatabaseAlways());
使用(var db=new MyDbContext())
{
db.Database.Log=s=>Console.WriteLine;
var p1=新的Parent1();
var p2=新的Parent2();
var c=新的子对象();
p1.儿童。添加(c);
p2.儿童。添加(c);
db.Parent1s.Add(p1);
db.Parent2s.Add(p2);
db.儿童.添加(c);
db.SaveChanges();
}
控制台。WriteLine(“按任意键退出”);
Console.ReadKey();
}
}
}