假设我的模型中有两个类:Product
和Category
。
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()
方法时,出现以下错误:
由于一个或多个外键属性不可为空,因此无法更改该关系。对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
有人可以驱使我朝正确的方向解决这个错误吗?
再次编辑
我发生的另一件事是,您可能正在孤立关系的另一端-您正在从“产品”中删除“类别”实体,但是您正在从该“类别”中删除“产品”吗?查看WillCascadeOnDelete(用于一对一或一个关系的实体框架(EF)代码第一个级联删除)或尝试在查询中包括这些关系-代替_ctx.Products.Where(...)
,使用_ctx.Products.Include(p => p.Categories).Where(...)
让我们知道如何为您服务!
已编辑
因此,基于洛伦佐的回应,我了解他正在尝试做的事情。过去,这是困扰我(也许还有几个人)的事情。
您可能正在查看“级联删除”问题-选择选项3(现在已不是必需的选项...)。
主要问题是这个(据我所知,因为我们不知道CategoriesPerProduct的模式:我们的作案者):您正在将CategoriesPerProduct中的条目置于不可能的状态,该状态要求存在Category,但是Category已有效地设置为null。
因此,您有几种选择:
_ctx.Categories.Remove(category);
)ctx.Entry(category).State = EntityState.Deleted
)本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句