EF6,注入dbContext缓存问题

时间:2017-08-03 15:50:14

标签: c# entity-framework caching dbcontext

我有一个EF即EF6项目,我在其中注入了我的DBContext,我对其进行了很少的LinQ查询,如图所示。 GetUnSentMessages()带回缓存数据,就像我在数据库中更改值时一样,它没有反映在我的查询结果中。 能否请您建议,我哪里出错了,解决方案是什么? 谢谢

更新 - GetUnSentMessages()获取未发送的消息.. UpdateMessageStatus() - 在发送未发送的消息后调用。

因此,如果我返回并更改SMSMessage表中的记录的任何值,它不会被GetUnsentMessages查询拾取..它仍然会带回旧数据......它的缓存内容..

<Buffer 00 00 53 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 53 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 00 00 1e 00 00 00 00 00>
<Buffer 00 00 1f 00 00 00 00 00>

更新2 - 在@Jaroslav Surala建议文章之后将我的代码更改为此,并且工作正常,不确定它是否是最佳/正确的方法 -

namespace SMSSender.Repositories
{
    public class SenderRepository : ISenderRepository
    {
        private SMSEntities entities;
        private ILog logger;

        public SenderRepository(SMSEntities entities, ILog logger)
        {
            this.entities = entities;
            this.logger = logger;
        }

        public IEnumerable<SMSMessage> GetUnSentMessages()
        {
            return entities.SMSMessage.Where(item => item.TimeSent == null && item.Deleted == 0 && item.StatusID == 0).ToList();
        }

        public void UpdateMessageStatus(int messageId, string mobileNo, short status)
        {
            var message = entities.SMSMessage.Where(item => item.MessageID == messageId && item.MobileNo == mobileNo).FirstOrDefault();
            if (message != null)
            {
                message.StatusID = status;
                message.TimeSent = DateTime.Now;
                entities.Entry(message).State = System.Data.Entity.EntityState.Modified;
                entities.SaveChanges();
            }
        }
    }
}

}

2 个答案:

答案 0 :(得分:1)

问题是EF6使用IdentityMap模式。您必须在更新后创建新的DB contetxt。这里http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/是关于它的好文章。

答案 1 :(得分:0)

DbContext初始化的那一刻,您在注释中指出的所有后续更改都将不会反映在您的DbContext的实例中,除非您进行刷新。

我希望以下代码段可以提供更简单的逻辑流程,您可以调整以适合您的应用程序。

using(var SMSEntities = new SMSEntities()
{
    // Your first query
    var messages = entities.SMSMessage
        .Where(item => item.TimeSent == null && item.Deleted == 0 && item.StatusID == 0)
        .ToList();

    // To simulate whatever you're doing in SSMS here.
    LongRunningMethod();

    // At this point, even when you re-query, you will not be getting the updated values.
    messages = entities.SMSMessage
        .Where(item => item.TimeSent == null && item.Deleted == 0 && item.StatusID == 0)
        .ToList();

    // To get updated values, do this.
    SMSEntities.Entry(messages).Reload();
    // Messages here will be updated with what you did in SSMS.
    messages = entities.SMSMessage
        .Where(item => item.TimeSent == null && item.Deleted == 0 && item.StatusID == 0)
        .ToList();
}

解释是这样,EF仍然会像往常一样进行数据库查询。现在,在从数据库返回结果后,EF意识到有一个messages列表,其中包含一组与您通过第一个查询获得的上下文(SMSEntities)绑定的ID。 EF将返回旧实体,这就是您认为的缓存。

您可以重新加载以强制刷新或简单地新建DbContext实例。