EF-从上级实体删除关系

洛伦佐

假设我的模型中有两个类:ProductCategory

public class Product
{
    public Product() {
        this.Categories = new HashSet<Category>();
    }

    [...]

    public virtual ICollection<Category> Categories { get; set; }
}

public class Category
{
    public Category() {
        this.Products = new HashSet<Product>();
    }

    [...]

    public virtual ICollection<Product> Products { get; set; }
}

产品具有许多类别,并且类别适用于许多产品。为了建立这种关系的模型,我的OnModelCreating方法中包含以下代码

    modelBuilder.Entity<Product>()
        .HasMany( p => p.Categories )
        .WithMany( p => p.Products )
        .Map( m => {
            m.MapLeftKey( "ProductID" );
            m.MapRightKey( "CategoryID" );
            m.ToTable( "CategoriesPerProduct" );
        } );
    modelBuilder.Entity<Category>()
        .HasMany( p => p.Products )
        .WithMany( p => p.Categories )
        .Map( m => {
            m.MapLeftKey( "CategoryID" );
            m.MapRightKey( "ProductID" );
            m.ToTable( "CategoriesPerProduct" );
        } );

这将创建一个新表,CategoriesPerProduct将MN关系分为两个1-N关系,这很适合我的需求。

现在,我需要更新与产品相关的类别,并且为了简化我的代码,我确实决定删除所有现有类别,然后像以下示例中一样重新添加新类别:

ICollection<Category> productCategories = product.Categories;
//First remove all existing categories 
foreach ( var category in productCategories ) {
    product.Categories.Remove( category );
}
// ..then add the new ones from input
foreach ( string categoryName in categories ) {
    Category c = await _ctx.Categories.SingleOrDefaultAsync( p => p.Description == categoryName );
    if ( c != null ) {
        product.Categories.Add( pc );
    }
    else {
        c = new ProductCategory() { Description = categoryName };
        _ctx.Categories.Add( c );
        await _ctx.SaveChangesAsync();
        product.Categories.Add( c );
    }
}
await _ctx.SaveChangesAsync();

不幸的是,当代码触及事务Commit()方法时,出现以下错误:

由于一个或多个外键属性不可为空,因此无法更改该关系。对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

有人可以驱使我朝正确的方向解决这个错误吗?

Funbrigade

再次编辑

我发生的另一件事是,您可能正在孤立关系的另一端-您正在从“产品”中删除“类别”实体,但是您正在从该“类别”中删除“产品”吗?查看WillCascadeOnDelete(用于一对一或一个关系的实体框架(EF)代码第一个级联删除)或尝试在查询中包括这些关系-代替_ctx.Products.Where(...),使用_ctx.Products.Include(p => p.Categories).Where(...)

让我们知道如何为您服务!

已编辑

因此,基于洛伦佐的回应,我了解他正在尝试做的事情。过去,这是困扰我(也许还有几个人)的事情。

您可能正在查看“级联删除”问题-选择选项3(现在已不是必需的选项...)。


看一下该关系无法更改,因为一个或多个外键属性不可为空

主要问题是这个(据我所知,因为我们不知道CategoriesPerProduct的模式:我们的作案者):您正在将CategoriesPerProduct中的条目置于不可能的状态,该状态要求存在Category,但是Category已有效地设置为null。

因此,您有几种选择:

  1. 使外键可为空(不推荐)
  2. 直接从DbContext中删除该项目(如_ctx.Categories.Remove(category);
  3. 将州标记为已删除(类似ctx.Entry(category).State = EntityState.Deleted

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

EF在单个表上级联删除

来自分类Dev

删除与EF6有多对多关系的实体记录

来自分类Dev

删除与EF6有多对多关系的实体记录

来自分类Dev

EF删除多对多关系

来自分类Dev

以1:1关系更新EF中的实体

来自分类Dev

当所需的关系为空时,为什么EF Core会删除实体?

来自分类Dev

如何以EF6代码优先的方式删除实体之间的关系?

来自分类Dev

无法删除需要父属性的ef实体

来自分类Dev

EF Core 5,删除多对多关系

来自分类Dev

EF Core>删除实体(软删除)>实体状态保持不变

来自分类Dev

在ef中更新实体

来自分类Dev

在ef中更新实体

来自分类Dev

EF核心关系查询

来自分类Dev

浏览EF中的关系

来自分类Dev

.NET核心EF关系

来自分类Dev

浏览EF中的关系

来自分类Dev

一对零或一对一关系的实体框架(EF)代码优先级联删除

来自分类Dev

EF核心多对多关系违反主键约束实体

来自分类Dev

EF中的多对多关系没有与实体的链接

来自分类Dev

将 DTO 映射到 EF 实体时处理关系

来自分类Dev

实体框架核心代码优先:在多对多关系上级联删除

来自分类Dev

如果删除两个EF实体之间的两个关系之一,另一个会被删除吗?

来自分类Dev

为什么EF在分离时会删除子实体?

来自分类Dev

删除实体导致验证错误EF6

来自分类Dev

动态实体EF5创建和*删除或回收* TypeBuilder

来自分类Dev

软删除EF Core中的嵌套实体

来自分类Dev

EF关系(1到0..1)不会被删除

来自分类Dev

在EF中插入/更新实体?

来自分类Dev

EF中的通用实体映射