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

时间:2015-05-15 18:25:28

标签: c# entity-framework ef-code-first entity-framework-6

EF 6,Code First

我希望为EF 6 TryGetLocalEntity()编写DbContext方法,该方法将按键查找实体,如果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。从这里开始,我想我可以根据DbContext了解如何在EntityKey中查找。

更新这是一个裂缝。显然是一些黑客攻击,我还没有测试过它:

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