use*_*064 227 c# entity-framework ef-database-first entity-framework-6
我正在尝试使用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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
每次我尝试使用上面的代码更新记录时,我收到此错误: -
{System.Data.Entity.Infrastructure.DbUpdateConcurrencyException:存储更新,插入或删除语句影响了意外的行数(0).自实体加载后,实体可能已被修改或删除.刷新ObjectStateManager entrie
Cra*_* W. 316
您正在尝试更新记录(对我而言,这意味着"更改现有记录上的值并将其保存回来").因此,您需要检索对象,进行更改并保存.
using (var db = new MyContextDB())
{
var result = db.Books.SingleOrDefault(b => b.BookNumber == bookNumber);
if (result != null)
{
result.SomeValue = "Some new value";
db.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
Mig*_*uel 141
我一直在审查实体框架的源代码,如果你知道Key属性,在其他情况下你需要检查AddOrUpdate实现,我找到了实际更新实体的方法:
public void Update<T>(T item) where T: Entity
{
// assume Entity base class have an Id property for all items
var entity = _collection.Find(item.Id);
if (entity == null)
{
return;
}
_context.Entry(entity).CurrentValues.SetValues(item);
}
Run Code Online (Sandbox Code Playgroud)
希望这有帮助!
nic*_*v80 47
您可以使用以下AddOrUpdate方法:
db.Books.AddOrUpdate(book); //requires using System.Data.Entity.Migrations;
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
小智 19
因此,您有一个已更新的实体,并且您希望使用最少量的代码在数据库中更新它...
并发总是很棘手,但我假设你只是希望你的更新获胜.这是我为同一个案例做的事情,并修改名称来模仿你的类.换句话说,只需attach改为add,它对我有用:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
Bon*_*lin 13
Attaching 一个实体会将其跟踪状态设置为Unchanged。要更新现有实体,您只需将跟踪状态设置为Modified。根据EF6 文档:
如果您知道某个实体已存在于数据库中,但可能已对其进行了更改,那么您可以告诉上下文附加该实体并将其状态设置为已修改。例如:
Run Code Online (Sandbox Code Playgroud)var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" }; using (var context = new BloggingContext()) { context.Entry(existingBlog).State = EntityState.Modified; // Do some more work... context.SaveChanges(); }
此代码是测试的结果,该测试仅更新一组列而不进行查询以首先返回记录.它首先使用Entity Framework 7代码.
// This function receives an object type that can be a view model or an anonymous
// object with the properties you want to change.
// This is part of a repository for a Contacts object.
public int Update(object entity)
{
var entityProperties = entity.GetType().GetProperties();
Contacts con = ToType(entity, typeof(Contacts)) as Contacts;
if (con != null)
{
_context.Entry(con).State = EntityState.Modified;
_context.Contacts.Attach(con);
foreach (var ep in entityProperties)
{
// If the property is named Id, don't add it in the update.
// It can be refactored to look in the annotations for a key
// or any part named Id.
if(ep.Name != "Id")
_context.Entry(con).Property(ep.Name).IsModified = true;
}
}
return _context.SaveChanges();
}
public static object ToType<T>(object obj, T type)
{
// Create an instance of T type object
object tmp = Activator.CreateInstance(Type.GetType(type.ToString()));
// Loop through the properties of the object you want to convert
foreach (PropertyInfo pi in obj.GetType().GetProperties())
{
try
{
// Get the value of the property and try to assign it to the property of T type object
tmp.GetType().GetProperty(pi.Name).SetValue(tmp, pi.GetValue(obj, null), null);
}
catch (Exception ex)
{
// Logging.Log.Error(ex);
}
}
// Return the T type object:
return tmp;
}
Run Code Online (Sandbox Code Playgroud)
这是完整的代码:
public interface IContactRepository
{
IEnumerable<Contacts> GetAllContats();
IEnumerable<Contacts> GetAllContactsWithAddress();
int Update(object c);
}
public class ContactRepository : IContactRepository
{
private ContactContext _context;
public ContactRepository(ContactContext context)
{
_context = context;
}
public IEnumerable<Contacts> GetAllContats()
{
return _context.Contacts.OrderBy(c => c.FirstName).ToList();
}
public IEnumerable<Contacts> GetAllContactsWithAddress()
{
return _context.Contacts
.Include(c => c.Address)
.OrderBy(c => c.FirstName).ToList();
}
//TODO Change properties to lambda expression
public int Update(object entity)
{
var entityProperties = entity.GetType().GetProperties();
Contacts con = ToType(entity, typeof(Contacts)) as Contacts;
if (con != null)
{
_context.Entry(con).State = EntityState.Modified;
_context.Contacts.Attach(con);
foreach (var ep in entityProperties)
{
if(ep.Name != "Id")
_context.Entry(con).Property(ep.Name).IsModified = true;
}
}
return _context.SaveChanges();
}
public static object ToType<T>(object obj, T type)
{
// Create an instance of T type object
object tmp = Activator.CreateInstance(Type.GetType(type.ToString()));
// Loop through the properties of the object you want to convert
foreach (PropertyInfo pi in obj.GetType().GetProperties())
{
try
{
// Get the value of the property and try to assign it to the property of T type object
tmp.GetType().GetProperty(pi.Name).SetValue(tmp, pi.GetValue(obj, null), null);
}
catch (Exception ex)
{
// Logging.Log.Error(ex);
}
}
// Return the T type object
return tmp;
}
}
public class Contacts
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Company { get; set; }
public string Title { get; set; }
public Addresses Address { get; set; }
}
public class Addresses
{
[Key]
public int Id { get; set; }
public string AddressType { get; set; }
public string StreetAddress { get; set; }
public string City { get; set; }
public State State { get; set; }
public string PostalCode { get; set; }
}
public class ContactContext : DbContext
{
public DbSet<Addresses> Address { get; set; }
public DbSet<Contacts> Contacts { get; set; }
public DbSet<State> States { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connString = "Server=YourServer;Database=ContactsDb;Trusted_Connection=True;MultipleActiveResultSets=true;";
optionsBuilder.UseSqlServer(connString);
base.OnConfiguring(optionsBuilder);
}
}
Run Code Online (Sandbox Code Playgroud)
你应该使用.如果要更新对象中的所有字段,请使用Entry()方法.另请注意,您无法更改字段ID(键),因此在编辑时首先将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();
}
Run Code Online (Sandbox Code Playgroud)
我找到了一种效果很好的方法。
var Update = context.UpdateTables.Find(id);
Update.Title = title;
// Mark as Changed
context.Entry(Update).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
对于.net core
context.Customer.Add(customer);
context.Entry(customer).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
小智 5
以下是此问题的最佳解决方案:在视图中添加所有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)
Run Code Online (Sandbox Code Playgroud)
在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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
477560 次 |
| 最近记录: |