在 EF 6/Code First 中通过键查找本地缓存的实体
Look up locally cached entity by key in EF 6 / Code First
EF 6,代码优先
我正在为 EF 6 DbContext
编写一个 TryGetLocalEntity()
方法,它将按键查找一个实体,如果它存在于 DbContext.Set<TEntity().Local
中,则 return 它。我想根据实体键而不是对象引用进行查找。
所以方法签名可能是:
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
中查找
更新 这里有一个破解。显然有些 hack,我还没有测试过:
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;
}
UPDATE 当实体存在于上下文中但尚未保存到数据库时,我所拥有的似乎有效 except .我一直在 EF 源中挖掘,试图确定 unsaved/added 实体是否没有 EntityKey
.
您可以使用:
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?
EF 6,代码优先
我正在为 EF 6 DbContext
编写一个 TryGetLocalEntity()
方法,它将按键查找一个实体,如果它存在于 DbContext.Set<TEntity().Local
中,则 return 它。我想根据实体键而不是对象引用进行查找。
所以方法签名可能是:
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
中查找
更新 这里有一个破解。显然有些 hack,我还没有测试过:
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;
}
UPDATE 当实体存在于上下文中但尚未保存到数据库时,我所拥有的似乎有效 except .我一直在 EF 源中挖掘,试图确定 unsaved/added 实体是否没有 EntityKey
.
您可以使用:
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?