Получение постоянной ссылки на сущность без вызова БД - PullRequest
0 голосов
/ 03 февраля 2011

Можно ли получить ссылку на уже существующий объект, для которого известен идентификатор без обращения к БД , как можно было бы сделать с NHibernate, используя ISession.Load(id)?

1 Ответ

1 голос
/ 03 февраля 2011

Да, это возможно, если объект уже загружен .В случае 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;

Пример чистого EF4:

var entity = context.CreateObject<MyEntity>();
entity.Id = id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...