【问题标题】:Delete Relationship Key in EF 4 with repository pattern and DbContext使用存储库模式和 DbContext 删除 EF 4 中的关系键
【发布时间】:2011-11-18 04:24:13
【问题描述】:

我正在使用 ASP.NET MVC、Sql Compact Edition、Entity Framework 4 以及带有 DbContext 的通用存储库模式。 当我想删除一个具有子实体或删除具有多对多关系的实体时,我遇到了一些问题。

我得到了错误: 操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

有很多帖子解释了它,但我被卡住了,因为这个例子很多解释都没有存储库模式或使用 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
        }
    }

服务调用它:

public class UserService : IUserService
{
    private readonly IUserRepository _userRepository;

    public UserService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public void DeleteUser(User user)
    {            
        _userRepository.Delete(user);

    }

    public void DeleteUser(int userId)
    {
        var user = _userRepository.GetById(userId);
        DeleteUser(user);
    }
}

我的意思是,我们可以只从存储库中调用删除服务,然后所有子对象都会自动删除吗?或者如果我必须一个一个地删除子实体,我该怎么做? 而且我不想使用级联修改数据库,因为当我更改模型并从模型生成数据库时,它会破坏一切。

更新:这是模型

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; }
}

提前谢谢你

【问题讨论】:

  • 你的意思是,如果你改变模型并生成数据库,一切都会被破坏?怎么了?

标签: c# asp.net-mvc generics entity-framework-4 repository-pattern


【解决方案1】:

在 EF 中映射实体时,您需要启用“级联删除”,以便在删除父级时删除所有子级。

HasRequired(child => child.Parent)
   .WithMany(parent => parent.Children)
   .HasForeignKey(child => child.ParentId)
   .WillCascadeOnDelete();

如果您正在对现有数据库进行建模,请确保使用“级联删除”设置外键。

【讨论】:

  • 如果我们只修改存储库模式代码有可能吗?不建模?
  • @Rivera 您必须先删除每个子实体,然后才能删除父实体。那将是一个糟糕的解决方案:)
  • 为什么会很糟糕?我已经发布了我的模型,所以如果您不介意,请根据我的模型更改答案:)
  • @Rivera 您正在尝试解决错误层中的问题。您必须检查每个子项目并删除它们(您可能会错过子实体)。如果您以后添加了不同的子集合,您将再次更新逻辑。
猜你喜欢
  • 2012-02-23
  • 2011-09-04
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多