我的公司正在更新旧产品的用户界面,以使其具有现代浏览器兼容性等。我们正在使用的一个限制是我们无法更改驱动它的数据库。不幸的是,数据库形成不良,因此,我们必须做一些不太好的事情来使这个工作。
其中一个缺点是添加,删除,更新等数据的过程都是通过存储过程完成的。由于有这么多特殊情况和奇怪的行为,我们在我们拥有的时间内绕过它们是不可行的。因此,我试图在适用时调用这些存储过程。这很有用,但Breeze似乎对我正在做的事情不满意。
更具体地说,当要添加特定实体时,我登陆自定义EF存储库的add方法,调用存储过程进行添加,并将实体的状态设置为不变。它被添加到数据库中,一切都继续正常,直到Breeze尝试从分配给新实际的临时负键修复密钥。不知何故,我需要告诉Breeze新密钥是什么,以便它可以解决,但在Breeze的文档中探索并没有让我到处都是。有任何想法吗?以下是相关代码。
Context Provider:
protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap)
{
foreach (KeyValuePair<Type, List<EntityInfo>> item in saveMap)
{
foreach (var entityItem in item.Value)
{
if (entityItem.Entity.GetType() == typeof (SerDevice))
{
var repo = new SerDeviceRepository(Context);
var entity = entityItem.Entity as SerDevice;
switch (entityItem.EntityState)
{
case EntityState.Added:
repo.Add(entity);
break;
}
SetEntityState(entityItem, EntityState.Unchanged);
}
}
}
return base.BeforeSaveEntities(saveMap);
}
SerDeviceRepository:
public override void Add(SerDevice entity)
{
var output =
_context.Database.ExecuteSqlCommand(
"exec usp_Device_Add @p0, @p1, @p2, @p3, @p4, @p5",
entity.DeviceName, entity.IpAddress, entity.CommsId,
entity.DeviceTypeId, entity.TemplateId, entity.DeviceStatus);
}
答案 0 :(得分:3)
对于遇到此问题的其他人来说,这就是我的修复方法。
在ContextProvider中,您可以选择覆盖名为AfterSaveEntities
的方法,该方法完全听起来像它所做的那样。您将获得此方法的两个参数:保存映射和键映射列表。这些键映射表明旧的临时密钥是什么以及新的真实密钥是什么。由于我通过将实体的状态设置为Unmodified来阻止Entity Framework执行其通常的工作,因此密钥没有得到更新,并且当AfterSaveEntities
被调用时,它在真正的密钥点中具有临时密钥并且{{1}在临时关键点。
修复很简单。只需将真实密钥移动到临时密钥点(因为它实际上是临时密钥),然后从null
检索刚刚添加到数据库中的项的密钥。当保存结束并返回客户端时,Breeze将不再是明智之举,并且会认为实体框架照常处理业务。
ExampleContextProvider.cs:
DbContext
如果您遇到同样的问题,我希望这会对您有所帮助!