C# 使用repository模式和DbContext删除EF 4中的关系键
我正在使用ASP.NET MVC、Sql Compact Edition、Entity Framework 4和DbContext的通用存储库模式。 当我想删除一个有子实体或删除具有多对多关系的实体时,我遇到了一些问题 我得到一个错误: 操作失败:无法更改关系,因为一个或多个外键属性不可为null。对关系进行更改时,相关外键属性设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象C# 使用repository模式和DbContext删除EF 4中的关系键,c#,asp.net-mvc,generics,entity-framework-4,repository-pattern,C#,Asp.net Mvc,Generics,Entity Framework 4,Repository Pattern,我正在使用ASP.NET MVC、Sql Compact Edition、Entity Framework 4和DbContext的通用存储库模式。 当我想删除一个有子实体或删除具有多对多关系的实体时,我遇到了一些问题 我得到一个错误: 操作失败:无法更改关系,因为一个或多个外键属性不可为null。对关系进行更改时,相关外键属性设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象 HasRequired(child => child.
HasRequired(child => child.Parent)
.WithMany(parent => parent.Children)
.HasForeignKey(child => child.ParentId)
.WillCascadeOnDelete();
有很多帖子对此进行了解释,但我被卡住了,因为很多例子都是在没有存储库模式或使用ObjectContext的情况下解释的
下面是我在存储库库中的一些代码以及我使用它的方式
public abstract class RepositoryBase<T> : IRepository<T> where T : class
{
private readonly DbContext _context;
private readonly IDbSet<T> _dbset;
protected RepositoryBase(DbContext dbContext)
{
_context = dbContext;
_dbset = _context.Set<T>();
}
public void Delete(T entity)
{
_dbset.Remove(entity);
Commit();
}
private void Commit()
{
try
{
_context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
var exceptionMessage = new StringBuilder();
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
exceptionMessage.AppendFormat("Property: {0} Error: {1}", validationError.PropertyName,
validationError.ErrorMessage);
}
}
throw; //so that we see the exception right away when we develop
}
}
我的意思是,我们可以从存储库中调用delete服务并自动删除所有子对象吗?或者,如果我必须逐个删除子实体,我该怎么做?
我不想用cascade修改数据库,因为当我改变模型并从模型生成数据库时,它会破坏所有的功能
更新:这是模型
public partial class User
{
public User()
{
this.EAConnections = new HashSet<EAConnection>();
this.UserRepositoryRoles = new HashSet<UserLinkRepositoryRole>();
}
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<EAConnection> EAConnections { get; set; }
public virtual ICollection<UserLinkRepositoryRole> UserRepositoryRoles { get; set; }
}
public partial class UserLinkRepositoryRole
{
public int UserRepositoryRoleId { get; set; }
public int UserId { get; set; }
public int RepositoryRoleId { get; set; }
public int EAConnectionId { get; set; }
public virtual User User { get; set; }
public virtual RepositoryRole RepositoryRole { get; set; }
public virtual EAConnection EAConnection { get; set; }
}
公共部分类用户
{
公共用户()
{
this.EAConnections=new HashSet();
this.UserRepositoryRoles=new HashSet();
}
public int UserId{get;set;}
公共字符串用户名{get;set;}
公共虚拟ICollection EAConnections{get;set;}
公共虚拟ICollection UserRepositoryRoles{get;set;}
}
公共部分类UserLinkRepositoryRole
{
public int UserRepositoryRoleId{get;set;}
public int UserId{get;set;}
公共int RepositoryRoleId{get;set;}
public int EAConnectionId{get;set;}
公共虚拟用户用户{get;set;}
公共虚拟RepositoryRole RepositoryRole{get;set;}
公共虚拟EAConnection EAConnection{get;set;}
}
提前感谢您在EF中映射实体时,您需要启用“级联删除”,以便在删除父项时删除所有子项
HasRequired(child => child.Parent)
.WithMany(parent => parent.Children)
.HasForeignKey(child => child.ParentId)
.WillCascadeOnDelete();
如果您正在对现有数据库建模,请确保foreignkey设置为“级联删除”。如果我们只是修改存储库模式代码,是否可能?不建模?@Rivera您必须在删除父实体之前删除每个子实体。这将是一个可怕的解决办法:)为什么会很可怕?我已经发布了我的模型,所以如果你不介意,请根据我的模型更改答案:)@Rivera你试图在错误的层中解决问题。您必须遍历每个子项并删除它们(您可能会错过子实体)。如果您以后添加了不同的子集合,那么您必须再次更新逻辑。您的意思是,如果您更改模型并生成数据库,那么所有内容都将被破坏?怎么了?