GenericRepository模式更新方法

时间:2014-10-29 16:46:49

标签: c# asp.net-mvc repository-pattern unit-of-work

我正在尝试使用unitofwork和存储库模式,我有以下内容"更新"如果我要替换表行(id,color,year)中的所有元素,该方法可以正常工作。

public virtual void Update(TEntity entityToUpdate)
{
    dbSet.Attach(entityToUpdate);
    (entityToUpdate).State = EntityState.Modified;
}

但我想更新我传递的特定列(id& color)。它将覆盖其他元素(年)。

例如,我的Cars表中有一个数据库记录:

Id = 1,
color = "red"
year = 2010

如果我这样更新......

var location = new Car
{
    Id = 1,
    color = "blue"
};


unitOfWork.CarRepository.Update(car);

记录现在是:

Id = 1,
color = "blue"
year = null 

如何重写我的通用存储库方法以更改我提供的内容? (即保持年份值)

2 个答案:

答案 0 :(得分:5)

您将无法合理地使用通用存储库模式。你真的没有必要使用这种模式。 EntityFramework已经是一个通用的存储库,为什么你需要将它包装在另一个通用的存储库中?这种抽象增加了负面价值。

您确实希望从控制器封装数据库使用情况(MVC控制器中不应该有DbContext),但是您不需要任何特殊模式。只需将DbContext注入到可以工作的类中。

如果您通过UOW,大部分工作模式也是反模式。这在您的应用程序中创建了一些非常疯狂的耦合问题,完全不相关的代码能够影响截然不同的代码段。

删除通用存储库并直接在服务/ DAL /资源类(无论您想要调用它)中使用EF将允许您使用EF的全部功能。这将允许非常简单地进行部分更新。

要使用通用存储库进行部分更新,您需要一些重型动态代码来处理映射。老实说,我理论上可以写这个,但我知道不写这个。越多越抽象的映射越脆弱,几乎不可能预测如何处理映射的未来。这就是为什么有像AutoMapper这样的整个库来处理无法完成映射组合的原因。 AutoMapper也有点用尽,虽然它可以做大致基本的自动化,但AutoMapper的用例仍然是静态映射而不是动态映射。您需要创建动态映射,即水晶球映射。

答案 1 :(得分:0)

您编写的更新方法假定您已经开始使用已设置属性的现有实体对象。存储库假定您的业务逻辑的工作方式如下:

var car = repo.GetCar(id);

car.prop1 = "new value";
car.prop2 = "another new value";

repo.update(car);

这将保留您之前设置的所有值。