繁体   English   中英

实体框架更新问题

[英]Entity Framework Update Problem

我正在使用Entity Framework和LINQ来检索数据。 我有以下问题:

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

在我致电之前,数据库中的字段正在更改:

db.SaveChanges();

我该如何避免这种情况?

在我致电之前,数据库中的字段正在更改

如果您要像在应用程序外部进行更改一样进行更改,则例如在SQL Management Studio中进行更改。 实体框架无法检测到这些更改,因此,您可能会获得由实体框架缓存的陈旧对象。 为了防止接收缓存的对象并从数据库获取最新值,请使用AsNoTracking。

尝试放入AsNoTracking():

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

或者,如果您的问题是检测对同一行的并发更新( 不幸的是 ,它并不仅适用于UPDATE),请使用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

检查是否将db对象传递给其他方法,并在那里调用SaveChanges()?

还是检查是否有异常的catch块,并且可能在catch块中使用SaveChanges()来记录错误消息?

(这些是常见的编程错误)

正如其他人所说,我相信您也在另一个地方使用上下文,并且另一个地方正在调用savechanges并更新所有内容。 尝试执行@Evan的using语句建议,以确保您具有新的上下文。

AsNoTracking不会确保您获得未在数据库中缓存的实体,其目的是不将对象放在上下文中。 如果使用AsNoTracking,然后更改查询中返回的实体,则需要在调用savechanges之前将它们修改后附加到上下文,否则它们将不会被更新。

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

我会在其他帖子上发表评论,但是没有足够的代表。

您能否再提供一些周围的代码? 如果不了解您如何构建上下文,可能会有些困难。

这通常是我处理更新的方式(希望它可以提供一些见解):

       using (var ctx = new myModel.myEntities())
        {
            int pollID = 1;
            var poll = (from p in ctx.Polls
                        where p.PollID == pollID
                        select p).FirstOrDefault();

            poll.Question = txtPoll.Text.Trim();
            ctx.SaveChanges();
        }

杰克·伍德沃德,你的没为我工作。

对于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();

这工作得更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM