Код элемента Entity Framework First ReadOnly Entity

Есть ли способ отметить объект как доступный только для чтения и не указывать для него какой-либо ключ?

Ответ 1

Есть несколько вещей, которые вы можете сделать для принудительного использования только для чтения в Code First. Во-первых, используйте AsNoTracking() при запросе.

var readOnlyPeople = (from p in context.People
                        where p.LastName == "Smith"
                        select p).AsNoTracking();

Это говорит Code First, чтобы не отслеживать изменения этих объектов, поэтому, когда вы вызываете SaveChanges(), никаких изменений, внесенных в эти объекты, не будет сохранено.

Взаимодействие, которое вы можете сделать, - установить состояние Unchanged перед вызовом SaveChanges().

context.Entry(person).State = EntityState.Unchanged;
context.SaveChanges();

Это говорит Code First игнорировать любые изменения, которые были внесены в этот объект.

Если у вас нет ключа, все объекты должны иметь ключ. Это может не обязательно отображаться на первичный ключ в базе данных, но он "должен однозначно идентифицировать экземпляр типа объекта в наборе сущностей".

Ответ 2

Используя первый код в EF6, я создал несколько объектов, которые отражают представления, которые, очевидно, не должны быть изменены или сохранены. Чтобы предотвратить изменение сущности, я использовал защищенные свойства набора:

public class TransplantCenterView
{
    public string TransplantsThisYear { get; protected set; }
}

Entity Framework все еще может установить это свойство, но другие разработчики не могут случайно сделать это без ошибки времени компиляции. Это отлично работает, но, похоже, лучшим решением было бы полное устранение отслеживания.


Благодаря ответу reggaeguitar, кажется, что есть ответ на этот вопрос (пожалуйста, также проголосуйте за его ответ, если это полезно), что позволило мне изменить мой код из:

public class MyContext : DbContext
{
    public DbSet<TransplantCenterVeiw> TransplantCenterViews {get; set;}
}

To:

public class MyContext : DbContext
{
    //appears the DbSet is still needed to make Set<Entity>() work
    protected DbSet<TransplantCenterView> _transplantCenterViews {get; set;}
    //this .AsNoTracking() disables tracking for our DbSet.
    public DbQuery<TransplantCenterView> TransplantCenterViews {
        get { return Set<TransplantCenterView>().AsNoTracking(); }
    }
}

Я не знаю никаких плюсов и минусов, но мой существующий код продолжал работать без каких-либо задержек, так что кажется победой.

Ответ 3

Если вы хотите, чтобы весь объект был доступен только для чтения, вы можете сделать это

/// Using a dbquery since this is readonly.
/// </summary>
public DbQuery<State> States
{
  get
  {
    // Don't track changes to query results
    return Set<State>().AsNoTracking();
 }
}

источник http://www.adamtuliper.com/2012/12/read-only-entities-in-entity-framework.html