Getting a persistent entity reference without a DB call

发布于 2022-09-06 08:56:14 字数 211 浏览 24 评论 0

Is it possible to get a reference to an already persistent object for which the id is known without a DB roundtrip, like one would do with NHibernate using ISession.Load(id)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

卷耳 2022-09-13 08:56:15

Yes it is possible if the object is already loaded. In case of EF Future CTP5 you can use new Local property of the DbSet<T> instance:

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

In case of ObjectContext the situation is little bit complicated - you need EntityKey instance which is cumbersome to get when working with POCOs.

Part of my repository code:

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;
    }
}

If the instance is not loaded you simply can't get the reference without querying DB. You can use dummy object creation.

CTP5 example:

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

Pure EF4 example:

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

or dummy object with proxy creation (CTP5 example):

CTP5 example:

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

Pure EF4 example:

var entity = context.CreateObject<MyEntity>();
entity.Id = id;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文