在两个级别上删除具有一对多关系的实体会导致外键异常

时间:2015-12-20 14:24:38

标签: c# entity-framework entity-framework-6

您好我正在尝试从两个级别上的一对多关系中删除该数据库中的实体。我正在使用实体框架6.

这是模块的数据库图表:

enter image description here

这是我的代码:

public partial class DatabaseContext : DbContext
{
    public DatabaseContext()
        : base("name=DatabaseContext")
    {
    }
          public virtual DbSet<Property> Properties { get; set; }
    public virtual DbSet<PropertyCategory> PropertyCategories { get; set; }
    public virtual DbSet<TemplateProperty> TemplateProperties { get; set; }
    public virtual DbSet<TemplateProperyCategory> TemplateProperyCategories { get; set; }
    public virtual DbSet<Template> Templates { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Property>()
        .HasMany(e => e.TemplateProperties)
        .WithRequired(e => e.Property)
        .WillCascadeOnDelete(false);

    modelBuilder.Entity<PropertyCategory>()
        .HasMany(e => e.TemplateProperyCategories)
        .WithRequired(e => e.PropertyCategory)
        .WillCascadeOnDelete(true);

    modelBuilder.Entity<TemplateProperyCategory>()
        .HasMany(e => e.TemplateProperties)
        .WithRequired(e => e.TemplateProperyCategory)
        .HasForeignKey(e => e.TemplatePropertyCategoryId)
        .WillCascadeOnDelete(true);

    modelBuilder.Entity<Template>()
        .HasMany(e => e.TemplateProperyCategories)
        .WithRequired(e => e.Template)
        .WillCascadeOnDelete(true);
    }
}


public class TemplateService : ITemplateService
{
    private readonly ITemplateUnitOfWork templateUnitOfWork;

    public TemplateService(ITemplateUnitOfWork templateUnitOfWork)
    {
        this.templateUnitOfWork = templateUnitOfWork;
    }

    public void Delete(TemplateDTO templateDTO)
    {
        var template = templateUnitOfWork.TemplateRepository.GetById(templateDTO.Id);
        templateUnitOfWork.TemplateRepository.Delete(template);
        templateUnitOfWork.SaveChanges();
    }
}

public class BaseUnitOfWork
{
    protected DatabaseContext DatabaseContext;

    public void SaveChanges()
    {

        bool saveFailed;
        do
        {
            saveFailed = false;
            try
            {
                DatabaseContext.SaveChanges();
                DatabaseContext.Dispose();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                saveFailed = true;
                ex.Entries.Single().Reload();
            }

        } while (saveFailed);
    }
}

public class TemplateUnitOfWork : BaseUnitOfWork, ITemplateUnitOfWork
{
    private IRepository<Template> templateRepository;

    public TemplateUnitOfWork(DatabaseContext databaseContext)
    {
        DatabaseContext = databaseContext;
    }


    public IRepository<Template> TemplateRepository
    {
        get
        {
            return templateRepository ?? (templateRepository =
                Injector.ResolverService.Resolve<IRepository<Template>>(DatabaseContext));
        }
    }

}

public class Repository<T> : IRepository<T> where T : class
{
    protected readonly DatabaseContext DatabaseContext;

    protected readonly DbSet<T> DbSet;

    public Repository(DatabaseContext databaseContext)
    {
        DatabaseContext = databaseContext;
        DbSet = DatabaseContext.Set<T>();
        DatabaseContext.Configuration.ValidateOnSaveEnabled = false;
    }

    public void Delete(T entity)
    {
        DbEntityEntry dbEntityEntry = DatabaseContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Deleted)
        {
            dbEntityEntry.State = EntityState.Deleted;
        }
        else
        {
            DbSet.Attach(entity);
            DbSet.Remove(entity);
        }
    }

    public virtual T GetById(int id)
    {
        return DbSet.Find(id);
    }
}

我希望能够从表格模板中删除一个元素。当发生这种情况时,我希望它从TemplatePropertyCategories中删除与它相关的所有元素,以及在TemplatePRoperties和TemplatePropertyCategories之间具有关系的所有元素。

生成databaseContext,从数据库工具中使用Visual Studios Code First。

当我加载模板实体时,它预先加载了templatePropertyCategories和templateProperties。

我认为为了使这个工作必须为自由表设置WillCascadeDelete(true)但是没有任何可见。

当我尝试运行此代码时,我得到了这个例外:

  

DELETE语句与REFERENCE约束冲突\&#34; FK_dbo.TemplateProperties_dbo.Templates_TemplateId \&#34;。冲突发生在数据库\&#34; TElectronics \&#34;,table \&#34; dbo.TemplateProperyCategories \&#34;,column&#39; TemplateId&#39;。\ r \ n该声明已终止&#34;}

更改结构,数据库不是一个选项。

任何人都知道如何才能使这项工作?

1 个答案:

答案 0 :(得分:0)

您忘记配置 TemplateProperty 实体

modelBuilder.Entity<TemplateProperty>()
    .HasRequired(t => t.TemplatePropertyCategory)
    .WithMany(t => t.TemplateProperties)
    .HasForeignKey(d => d.TemplatePropertyCategoryId)
    .WillCascadeOnDelete(true);