Entity Framework 通过实体变更追踪(ChangeTracker)来维护实体的变更情况,最终通过调用SaveChanges将变更保存到数据库,有人认为着很简单,其实不然,下面以Students为例添加和更新数据
添加
students
public class students
{
public string id { get; set; }
public string name { get; set; }
public int age { get; set; }
public DateTime createtime { get; set; }
public DateTime modifydate { get; set; }
}
studentsMap
public studentsMap()
{
ToTable("students");
HasKey(p => p.id);
Property(p => p.id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None).IsRequired();
Property(p => p.name).HasColumnType("VARCHAR").HasMaxLength(20).IsRequired();
Property(p => p.createtime).IsRequired();
Property(p => p.modifydate).IsRequired();
Property(p => p.age).IsRequired();
}
demo
using (var db=new Model1())
{
students ss = new students()
{
id = "1",
name = "chen",
age = 99,
createtime = DateTime.Now,
modifydate=DateTime.Now
};
db.StudentTests.Add(ss);
if (db.SaveChanges() > 0)
MessageBox.Show("success");
else
MessageBox.Show("failed");
}
更新
更新是最为复杂的操作,不知道平时大家都是怎么操作的,因为entity framework没有对应Update的方法,或许你会立马想到将实体的状态修改为modified,这真的管用吗?
public students createStu()
{
return new students()
{
id = "1",
name = "chen",
age = 199,
createtime = DateTime.Now,
modifydate = DateTime.Now
};
}
using (var db = new Model1())
{
students ss = createStu();
var id1 = db.StudentTests.Where(p => p.id == "1").FirstOrDefault();
if (id1 !=null)
{
db.StudentTests.Attach(ss);
db.Entry(ss).State = System.Data.Entity.EntityState.Modified;
if (db.SaveChanges() > 0)
MessageBox.Show("success");
else
MessageBox.Show("failed");
}
}
此时更新失败,Attach的含义是,如果附加的对象存在于数据库中但是未被上下文追踪,那么使用attach将使得ss被追踪,但是ss已经存在,所以报相同键的错误,这时我们只需要设置关闭追踪即可解决这个问题。
关闭追踪AsNoTracking,需要注意修改实体的状态更改代码需要放在Attach方法后执行,关闭追踪后,更新数据库成功
using (var db = new Model1())
{
students ss = createStu();
var id1 = db.StudentTests.AsNoTracking().Where(p => p.id == "1").FirstOrDefault();
if (id1 !=null)
{
db.StudentTests.Attach(ss);
db.Entry(ss).State = System.Data.Entity.EntityState.Modified;
if (db.SaveChanges() > 0)
MessageBox.Show("success");
else
MessageBox.Show("failed");
}
}
将实体状态更改为Modified是将实体全部字段进行更新,假如我们只想更改其中的某些字段则可以这么做
- 直接修改查询出来的实体的属性,并保存
using (var db = new Model1())
{
students ss = createStu();
var id1 = db.StudentTests.Where(p => p.id == "1").FirstOrDefault();
if (id1 !=null)
{
id1.age = ss.age;
id1.name = ss.name;
if (db.SaveChanges() > 0)
MessageBox.Show("success");
else
MessageBox.Show("failed");
}
}
- 直接将ss附加到上下文,手动设置修改
using (var db = new Model1())
{
students ss = createStu();
db.StudentTests.Attach(ss);
db.Entry(ss).Property(p => p.age).IsModified = true;
if (db.SaveChanges() > 0)
MessageBox.Show("success");
else
MessageBox.Show("failed");
}
- 使用Entry()CurrentValues.SetValues()解决并发赋值
using (var db = new Model1())
{
students ss = createStu();
var id1 = db.StudentTests.Where(p => p.id == "1").FirstOrDefault();
if (id1 !=null)
{
db.Entry(id1).CurrentValues.SetValues(ss);
if (db.SaveChanges() > 0)
MessageBox.Show("success");
else
MessageBox.Show("failed");
}
}
- 批量更新
using (var db = new Model1())
{
var test = db.StudentTests
.Where(p => p.name == "chen").ToList();
test.ForEach(p => p.age = 1234);
db.SaveChanges();
}