我正在尝试使用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
如何重写我的通用存储库方法以更改我提供的内容? (即保持年份值)
答案 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);
这将保留您之前设置的所有值。