Проблема обновления Entity Framework - PullRequest
2 голосов
/ 07 августа 2011

Я использую Entity Framework & LINQ для получения данных.У меня проблема со следующим:

var customer= db.customers.where(c=>c.id==1);
customer.name=santhosh;
customer.city=hyd;

Поля в базе данных меняются до того, как я позвоню:

db.SaveChanges();

Как мне избежать этого?

Ответы [ 5 ]

2 голосов
/ 07 августа 2011

Как уже говорили другие, я полагаю, что вы используете свой контекст и в другом месте, и что другое местоположение вызывает сохранение изменений и обновляет все. Попробуйте сделать то, что предложил @Evan с использованием статистики, чтобы убедиться, что у вас свежий контекст.

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

    var customer= db.customers.AsNoTracking().Single(c=>c.id==1);
    customer.name=santhosh;
    customer.city=hyd;
    ctx.customers.Attach(customer);

    ctx.ObjectStateManager.ChangeObjectState(customer, System.Data.EntityState.Modified);

Я бы только прокомментировал другие посты, но у меня еще недостаточно представителей.

2 голосов
/ 07 августа 2011

поля меняются в базе данных, прежде чем я позвоню

Если вы имеете в виду изменение как при изменении вне приложения, например, изменения в SQL Management Studio. Entity Framework не может обнаружить эти изменения, поэтому в результате вы можете получить устаревшие объекты, которые были кэшированы Entity Framework. Чтобы предотвратить получение кэшированного объекта и получение актуальных значений из базы данных, используйте AsNoTracking.

Попробуйте поставить AsNoTracking ():

var customer= db.customers.AsNoTracking().where(c=>c.id==1);
customer.name=santhosh;
customer.city=hyd;
db.SaveChanges();

Или, если ваша проблема заключается в обнаружении одновременных обновлений ( неудачная терминология , это не относится только к ОБНОВЛЕНИЮ) для той же строки, используйте тип поля rowversion (aka timestamp); затем в свой код .NET добавьте атрибут Timestamp к свойству. Пример: http://www.ienablemuch.com/2011/07/entity-framework-concurrency-checking.html

public class Song
{
    [Key]
    public int SongId { get; set; }
    public string SongName { get; set; }
    public string AlbumName { get; set; }

    [Timestamp]
    public virtual byte[] Version { get; set; }
}

ОБНОВЛЕНИЕ (после вашего комментария) :

Если вы действительно не намерены сохранять изменения вашего объекта в базе данных. Попробуйте отсоединить объект.

Попробуйте это:

var customer= db.customers.where(c=>c.id==1);
db.Entry(customer).State = System.Data.EntityState.Detached; // add this
customer.name=santhosh;
customer.city=hyd;    
db.SaveChanges();

Это не сохранит ваши изменения имени и города в базе данных.

Если вы хотите что-то более надежное (приведенное выше не даст исключение, если объект еще не был присоединен), создайте помощника:

private static void Evict(DbContext ctx, Type t, 
    string primaryKeyName, object id)
{            
    var cachedEnt =
        ctx.ChangeTracker.Entries().Where(x =>   
            ObjectContext.GetObjectType(x.Entity.GetType()) == t)
            .SingleOrDefault(x =>
        {
            Type entType = x.Entity.GetType();
            object value = entType.InvokeMember(primaryKeyName, 
                                System.Reflection.BindingFlags.GetProperty, 
                                null, x.Entity, new object[] { });
 
            return value.Equals(id);
        });
 
    if (cachedEnt != null)
        ctx.Entry(cachedEnt.Entity).State = EntityState.Detached;
}

Для использования: Evict(yourDbContextHere, typeof(Product), "ProductId", 1);

http://www.ienablemuch.com/2011/08/entity-frameworks-nhibernate.html

2 голосов
/ 07 августа 2011

Проверьте, передаете ли вы объект db какому-либо другому методу, и там ли вызывается SaveChanges ()?

Или проверьте, есть ли у вас блок перехвата исключения, и вы можете использовать SaveChanges () в блоке перехвата для записи сообщения об ошибке?

(Это распространенные ошибки программирования)

1 голос
/ 07 августа 2011

Можете ли вы дать немного больше окружающего кода?Может быть немного сложно, не видя, как вы создаете свой контекст.

Вот как я обычно обращаюсь с обновлениями (надеюсь, это может дать некоторое понимание):

0 голосов
/ 10 августа 2012

Джек Вудворд, у меня твое не сработало.

Мне пришлось немного изменить его для SQL Compact.

var customer= db.customers.AsNoTracking().Single(c=>c.id==1);     

db.customers.Attach(customer);      
customer.name=santhosh;     
customer.city=hyd;     
db.ObjectStateManager.ChangeObjectState(customer, System.Data.EntityState.Modified); 
db.SaveChanges();

db.Dispose();

Это работало намного лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...