c# - entity framework database first database changes




如何使用Entity Framework 6更新记录? (8)

你应该使用。 Entry()方法,以防您想要更新对象中的所有字段。 另外请记住,您不能更改字段ID(键),因此首先将ID设置为某些您编辑。

using(var context = new ...())
{
    var EditedObj = context
        .Obj
        .Where(x => x. ....)
        .First();

    NewObj.Id = EditedObj.Id; //This is important when we first create an object (NewObj), in which the default Id = 0. We can not change an existing key.

    context.Entry(EditedObj).CurrentValues.SetValues(NewObj);

    context.SaveChanges();
}

我正在尝试使用EF6更新记录。 首先查找记录,如果存在,则更新它。 这是我的代码: -

var book = new Model.Book
{
    BookNumber =  _book.BookNumber,
    BookName = _book.BookName,
    BookTitle = _book.BookTitle,
};
using (var db = new MyContextDB())
{
    var result = db.Books.SingleOrDefault(b => b.BookNumber == bookNumber);
    if (result != null)
    {
        try
        {
            db.Books.Attach(book);
            db.Entry(book).State = EntityState.Modified;
            db.SaveChanges();
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

每次尝试使用上述代码更新记录时,我都会收到此错误: -

{System.Data.Entity.Infrastructure.DbUpdateConcurrencyException:存储更新,插入或删除语句会影响意外数量的行(0)。 自实体加载后,实体可能已被修改或删除。 刷新ObjectStateManager的entrie


你应该删除db.Books.Attach(book);


尝试一下....

的UpdateModel(书);

var book = new Model.Book
{
    BookNumber =  _book.BookNumber,
    BookName = _book.BookName,
    BookTitle = _book.BookTitle,
};
using (var db = new MyContextDB())
{
    var result = db.Books.SingleOrDefault(b => b.BookNumber == bookNumber);
    if (result != null)
    {
        try
        {
            UpdateModel(book);
            db.Books.Attach(book);
            db.Entry(book).State = EntityState.Modified;
            db.SaveChanges();
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

您可以使用AddOrUpdate方法:

db.Books.AddOrUpdate(book); //requires using System.Data.Entity.Migrations;
db.SaveChanges();

我一直在审查实体框架的源代码,并找到了一种实际更新实体的方法,如果在其他情况下知道Key属性,则需要检查AddOrUpdate实现:

public void Update(T item)
{
    var entity = _collection.Find(item.Id);
    if (entity == null)
    {
        return;
    }

    _context.Entry(entity).CurrentValues.SetValues(item);
}

希望这个帮助!


所以你有一个更新的实体,你想用最少的代码在数据库中更新它...并发总是很棘手,但我假设你只是想让你的更新获胜。 下面是我为了同样的情况做了它,并修改了名称来模仿你的类。 IOW,只需更改附加添加,它适用于我:

public static void SaveBook(Model.Book myBook)
    {
        using (var ctx = new BookDBContext())
        {
            ctx.Books.Add(myBook);
            ctx.Entry(myBook).State = System.Data.Entity.EntityState.Modified;
            ctx.SaveChanges();
        }
    }

这是我的后RIA实体更新方法(对于Ef6时间帧):

public static void UpdateSegment(ISegment data)
{
    if (data == null) throw new ArgumentNullException("The expected Segment data is not here.");

    var context = GetContext();

    var originalData = context.Segments.SingleOrDefault(i => i.SegmentId == data.SegmentId);
    if (originalData == null) throw new NullReferenceException("The expected original Segment data is not here.");

    FrameworkTypeUtility.SetProperties(data, originalData);

    context.SaveChanges();
}

请注意, FrameworkTypeUtility.SetProperties()是一个很小的实用程序函数,我早在NuGet上的AutoMapper之前写过:

public static void SetProperties<TIn, TOut>(TIn input, TOut output, ICollection<string> includedProperties)
    where TIn : class
    where TOut : class
{
    if ((input == null) || (output == null)) return;
    Type inType = input.GetType();
    Type outType = output.GetType();
    foreach (PropertyInfo info in inType.GetProperties())
    {
        PropertyInfo outfo = ((info != null) && info.CanRead)
            ? outType.GetProperty(info.Name, info.PropertyType)
            : null;
        if (outfo != null && outfo.CanWrite
            && (outfo.PropertyType.Equals(info.PropertyType)))
        {
            if ((includedProperties != null) && includedProperties.Contains(info.Name))
                outfo.SetValue(output, info.GetValue(input, null), null);
            else if (includedProperties == null)
                outfo.SetValue(output, info.GetValue(input, null), null);
        }
    }
}

这是解决此问题的最佳解决方案:在视图中添加所有ID(键)。 考虑有多个表名为(第一,第二和第三)

@Html.HiddenFor(model=>model.FirstID)
@Html.HiddenFor(model=>model.SecondID)
@Html.HiddenFor(model=>model.Second.SecondID)
@Html.HiddenFor(model=>model.Second.ThirdID)
@Html.HiddenFor(model=>model.Second.Third.ThirdID)

在C#代码中,

[HttpPost]
public ActionResult Edit(First first)
{
  if (ModelState.Isvalid)
  {
    if (first.FirstID > 0)
    {
      datacontext.Entry(first).State = EntityState.Modified;
      datacontext.Entry(first.Second).State = EntityState.Modified;
      datacontext.Entry(first.Second.Third).State = EntityState.Modified;
    }
    else
    {
      datacontext.First.Add(first);
    }
    datacontext.SaveChanges();
    Return RedirectToAction("Index");
  }

 return View(first);
}




ef-database-first