在 EF 6 / Code First 中按键查找本地缓存的实体

Posted

技术标签:

【中文标题】在 EF 6 / Code First 中按键查找本地缓存的实体【英文标题】:Look up locally cached entity by key in EF 6 / Code First 【发布时间】:2015-05-15 18:25:28 【问题描述】:

EF 6,代码优先

我希望为 EF 6 DbContext 编写一个 TryGetLocalEntity() 方法,该方法将按键查找一个实体,如果它存在于 DbContext.Set<TEntity().Local 中,则返回它。我想根据实体键而不是对象引用进行查找。

所以方法签名可能是:

    public static bool TryGetLocalEntity<TContext, TEntity>(this TContext context, TEntity entity, out TEntity cachedEntity)
        where TContext : DbContext
        where TEntity : class
    

        EntityKey key = ???GetEntityKey???(entity);
        cachedEntity = context.Set<TEntity>().Local.Where(e => ???).FirstOrDefault();
        return cachedEntity != null;
    

这样做的目的是获取一个已从另一个源反序列化的实体,或者 1) Attach() 如果它在本地不存在(由实体键而不是对象引用确定),则它到 DbContext 或2) 检索本地缓存的实体(如果它确实存在)(再次由实体键而不是对象引用确定)。我知道我可以从数据库中获取它,但如果我已经拥有我需要的东西,我想避免往返。

我认为我缺少的主要步骤是从分离的 POCO 实体创建 EntityKey。从这里,我想我可以根据EntityKey 弄清楚如何在DbContext 中查找。

更新这是一个破解。显然有一些技巧,我还没有测试过:

using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.Pluralization;

    public static bool TryGetLocalEntity<TContext, TEntity>(this TContext context, TEntity entity, out TEntity cachedEntity)
        where TContext : DbContext
        where TEntity : class
    
        EnglishPluralizationService pluralizationService = new EnglishPluralizationService();
        string setName = pluralizationService.Pluralize(typeof(TEntity).Name);
        ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
        EntityKey key = objectContext.CreateEntityKey(setName, entity);
        try
        
            cachedEntity = objectContext.GetObjectByKey(key) as TEntity;
        
        catch (ObjectNotFoundException)
        
            cachedEntity = null;
        
        return cachedEntity != null;
    

更新当实体存在于上下文中但尚未保存到数据库中时,我所拥有的似乎工作除了。我一直在 EF 源中进行挖掘,试图确定未保存/添加的实体是否没有 EntityKey

【问题讨论】:

【参考方案1】:

你可以使用:

var objContext = ((IObjectContextAdapter)context).ObjectContext;
var objSet = objContext.CreateObjectSet<TEntity>();
var entityKey = objContext.CreateEntityKey(objSet.EntitySet.Name, entity);
https://msdn.microsoft.com/en-us/library/system.data.entity.core.objects.objectcontext.createentitykey%28v=vs.113%29.aspx Generic Way to Check If Entity Exists In Entity Framework?

【讨论】:

嘿嘿,好像是 4 分钟前,我可能正在打字:/ 我在完善它的同时不断编辑,以免人们浪费时间。也许不是最好的方法哈哈

以上是关于在 EF 6 / Code First 中按键查找本地缓存的实体的主要内容,如果未能解决你的问题,请参考以下文章

EF 4.1:使用 Fluent 映射从 Code First 中查找关键属性类型

20.2.翻译系列:EF 6中基于代码的数据库迁移技术EF 6 Code-First系列

15.翻译系列:EF 6中的级联删除EF 6 Code-First 系列

20.翻译系列:Code-First中的数据库迁移技术EF 6 Code-First系列

EF 6.1 Code First 中与不同主键的一对一关系

9.6 翻译系列:数据注解之Index特性EF 6 Code-First系列