Breeze在使用自定义代码添加实体的密钥修复时失败

时间:2014-01-27 18:04:23

标签: c# entity-framework entity-framework-5 breeze

我的公司正在更新旧产品的用户界面,以使其具有现代浏览器兼容性等。我们正在使用的一个限制是我们无法更改驱动它的数据库。不幸的是,数据库形成不良,因此,我们必须做一些不太好的事情来使这个工作。

其中一个缺点是添加,删除,更新等数据的过程都是通过存储过程完成的。由于有这么多特殊情况和奇怪的行为,我们在我们拥有的时间内绕过它们是不可行的。因此,我试图在适用时调用这些存储过程。这很有用,但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);
}

1 个答案:

答案 0 :(得分:3)

对于遇到此问题的其他人来说,这就是我的修复方法。

在ContextProvider中,您可以选择覆盖名为AfterSaveEntities的方法,该方法完全听起来像它所做的那样。您将获得此方法的两个参数:保存映射和键映射列表。这些键映射表明旧的临时密钥是什么以及新的真实密钥是什么。由于我通过将实体的状态设置为Unmodified来阻止Entity Framework执行其通常的工作,因此密钥没有得到更新,并且当AfterSaveEntities被调用时,它在真正的密钥点中具有临时密钥并且{{1}在临时关键点。

修复很简单。只需将真实密钥移动到临时密钥点(因为它实际上是临时密钥),然后从null检索刚刚添加到数据库中的项的密钥。当保存结束并返回客户端时,Breeze将不再是明智之举,并且会认为实体框架照常处理业务。

ExampleContextProvider.cs:

DbContext

如果您遇到同样的问题,我希望这会对您有所帮助!