在没有DB调用的情况下获取持久性实体引用

时间:2011-02-02 22:25:19

标签: .net entity-framework ef-code-first

是否可以获取对已知持久对象的引用,其中id为而没有DB往返,就像使用ISession.Load(id)的NHibernate一样?

1 个答案:

答案 0 :(得分:1)

是的,如果对象已加载,则可以。对于EF Future CTP5,您可以使用Local实例的新DbSet<T>属性:

var entity = context.MySet.Local.SingleOrDefault(e => e.Id == id);

如果ObjectContext情况有点复杂 - 您需要EntityKey实例,这在使用POCO时很麻烦。

我的存储库代码的一部分:

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
    private readonly EntitySetBase _entitySet;
    private readonly string _entitySetName;

    protected BaseObjectContext Context { get; set; }
    protected ObjectSet<TEntity> ObjectSet { get; set; }

    public Repository(BaseObjectContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }


        Context = context;
        ObjectSet = context.CreateObjectSet<TEntity>();

        var container = Context.MetadataWorkspace
            .GetEntityContainer(Context.DefaultContainerName, DataSpace.CSpace);
        _entitySet = container.BaseEntitySets
            .Single(es => es.ElementType.Name == typeof (TEntity).Name);
        _entitySetName = Context.DefaultContainerName + "." + _entitySet.Name;
    }

    public virtual IQueryable<TEntity> GetQuery()
    {
        return ObjectSet;
    }

    public virtual TEntity GetById(long id)
    {
        TEntity entity = TryGetLocalEntity(id);

        if (entity == null)
        {
            entity = GetQuery().SingleOrDefault(o => o.Id == id);
        }

        return entity;
    }

    private TEntity TryGetLocalEntity(long id)
    {
        if (_entitySet == null)
        {
            return null;
        }

        var key = new EntityKey(_entitySetName, "Id", id);
        ObjectStateEntry entry;

        if (Context.ObjectStateManager.TryGetObjectStateEntry(key, out entry))
        {
            return (TEntity) entry.Entity;
        }

        return null;
    }
}

如果未加载实例,则无法在不查询DB的情况下获取引用。您可以使用虚拟对象创建。

CTP5示例:

var entity = new MyEntity { Id = id };
context.MySet.Attach(entity);

Pure EF4示例:

var entity = new MyEntity { Id = id };
context.Attach(entity);

或具有代理创建的虚拟对象(CTP5示例):

CTP5示例:

var entity = context.MySet.Create();
enity.Id = id;

Pure EF4示例:

var entity = context.CreateObject<MyEntity>();
entity.Id = id;