0

我对一个系统有一个非常复杂的问题,当用户使用 asp webforms 提交页面时,将运行许多存储的过程。它会更新或删除相关表中的某些项目,但由于这一切都发生在存储过程中,linq to sql 不知道这个逻辑,所以它的缓存仍然在那里,删除的项目在它的缓存中。

我看到的问题归结为正在更新基于复合键的表,因此所有内容都通过存储过程删除,然后重新创建项目并插入新值,但是如果您假设实体看起来像:

public class SomeCompositeEntity
{
    public long UserId {get;set;}
    public smallint ActionTypeId {get;set;}
    public int ActionValue {get;set;}
}

所以在这种情况下,如果我有 10 个,并更新了 3 个,所有这些都将通过这个存储过程被删除,然后将被重新创建,其中 7 个与现有的相同,3 个是相同的 ID,但值不同。

问题是虽然删除只发生在数据库空间中,但 linq 并不知道这一点,所以当您尝试保存这些 linq 到 sql 的实体时,它仍然会因 DuplicateKeyException 而爆炸,这是正确的做法。

因此,如果我要捕获 DuplicateKeyException 然后获取实体并告诉 linq to sql 刷新它,覆盖数据库中的更改,如果它已被删除,它会从缓存中删除对象吗?因为文档对此并不清楚?

我很想删除存储过程和许多其他令人费解的过程,但客户坚持认为它不能更改,以防它以某种方式触发天数的结束......所以考虑到我在这里的位置,如果有任何其他关于如何处理这种情况的想法,那就太好了。

4

1 回答 1

0

目前我不得不做一件讨厌的事情......并在每次保存之前清空 Linq 的缓存。我试图对异常做出反应并处理它,但我无法将对象更新为处于更改状态,因此尝试积极主动并阻止异常发生,但这需要我检查项目是否在缓存中,如果是这样删除它们或交换/合并它们,错误仍然存​​在。

因此,无论如何,这是我最终使用的代码,虽然很糟糕,但确实可以完成工作,因为当我实现 Ninject(具有基于请求的范围)时,我也将转向短暂的连接,然后希望这将不再是一个问题。

public static void ClearEntityCache(this IDataContext dataContext)
        {
            const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            var method = dataContext.GetType().GetMethod("ClearCache", flags);
            method.Invoke(dataContext, null);
        }

上面的 IDataContext 是一个简单的包装接口,用于模拟数据层以进行单元测试。

于 2013-06-27T08:12:44.580 回答