EF外键约束和存储库模式

时间:2011-08-02 21:02:04

标签: entity-framework repository-pattern

我在asp.net mvc应用程序中有这个简单的Delete Get和Post方法

public ActionResult Delete(int ehrId, int id)
        {
            EHR ehr = ehrRepository.FindById(ehrId);
            PhysicalTest test = ehr.PhysicalTests.Where(t => t.ID == id).Single();
            return View(test);
        }


        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int ehrId, int id)
        {
            EHR ehr = ehrRepository.FindById(ehrId);
            PhysicalTest test = ehr.PhysicalTests.Where(t => t.ID == id).Single();
            ehr.PhysicalTests.Remove(test);
            unitOfWork.Commit();
            TempData["Success"] = "You have deleted the Physical Test Succesfully";
            return RedirectToAction("Index");
        }

问题是,当我尝试以这种方式删除子对象时,EF会抱怨

  

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

一个答案是使用PhysicalTest(子元素)存储库而不是EHRRepository ..但这似乎不是一个好的解决方案,因为我想强制执行始终通过父对象查询的安全性,以避免用户编辑/删除不属于他的物理测试。

我希望将我的存储库限制为只是聚合根。

继承我当前的SqlRepository通用实现....我愿意接受建议。

public class SqlRepository<T> : IRepository<T>
                                    where T : class, IEntity {

        internal SummumnetDB context;
        internal DbSet<T> _objectSet;

        public SqlRepository(SummumnetDB context)
        {
            this.context = context;
            this._objectSet = context.Set<T>();
        }


       public IQueryable<T> Find(Expression<Func<T, bool>> predicate) {
            return _objectSet.Where(predicate);
        }

        public void Add(T newEntity) {
            _objectSet.Add(newEntity);
        }

        public void Remove(T entity) {
            _objectSet.Remove(entity);
        }

        public IQueryable<T> FindAll()
        {
            return _objectSet;
        }

        public T FindById(int id)
        {
            return _objectSet.Single(o => o.ID == id);
        }


    }

1 个答案:

答案 0 :(得分:0)

EHRPhysicalTest表单聚合EHRPhysicalTest的聚合根目录,因为如果没有EHR,PhyscialTest就不能存在(您的例外情况表明FK在{ {1}}不能为null)。存储库应该存在于每个聚合根,它应该提供处理关系的特定方法。

是的,它不是通用的,因为具有不同配置和要求的实体的通用方法不起作用。

您的代码有什么问题?调用PhysicalTest不会删除测试。它只会将其FK设置为​​null。要删除ehr.PhysicalTests.Remove(test),您必须真正致电test。要允许直接删除,您必须使用identifying relation

相关问题